-
-
Notifications
You must be signed in to change notification settings - Fork 991
/
ftraits.hpp
124 lines (99 loc) · 2.93 KB
/
ftraits.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#pragma once
#include "indexer/feature_data.hpp"
#include "indexer/ftypes_mapping.hpp"
#include "coding/csv_reader.hpp"
#include "platform/platform.hpp"
#include "base/assert.hpp"
#include "base/logging.hpp"
#include <array>
#include <cstdint>
#include <initializer_list>
#include <optional>
#include <sstream>
#include <string>
#include <utility>
namespace ftraits
{
template <typename Base, typename Value>
class TraitsBase
{
public:
static std::optional<Value> GetValue(feature::TypesHolder const & types)
{
auto const & instance = Instance();
auto const it = Find(types);
if (!instance.m_matcher.IsValid(it))
return std::nullopt;
return it->second;
}
static std::optional<uint32_t> GetType(feature::TypesHolder const & types)
{
auto const & instance = Instance();
auto const it = Find(types);
if (!instance.m_matcher.IsValid(it))
return std::nullopt;
return it->first;
}
private:
using ConstIterator = typename ftypes::HashMapMatcher<uint32_t, Value>::ConstIterator;
static ConstIterator Find(feature::TypesHolder const & types)
{
auto const & instance = Instance();
auto const excluded = instance.m_excluded.Find(types);
if (instance.m_excluded.IsValid(excluded))
return instance.m_matcher.End();
return instance.m_matcher.Find(types);
}
protected:
static TraitsBase const & Instance()
{
static Base instance;
return instance;
}
ftypes::HashMapMatcher<uint32_t, Value> m_matcher;
ftypes::HashSetMatcher<uint32_t> m_excluded;
};
enum class WheelchairAvailability
{
No,
Yes,
Limited,
};
inline std::string DebugPrint(WheelchairAvailability wheelchair)
{
switch (wheelchair)
{
case WheelchairAvailability::No: return "No";
case WheelchairAvailability::Yes: return "Yes";
case WheelchairAvailability::Limited: return "Limited";
}
UNREACHABLE();
}
class Wheelchair : public TraitsBase<Wheelchair, WheelchairAvailability>
{
friend TraitsBase;
using TypesInitializer = std::initializer_list<std::initializer_list<char const *>>;
Wheelchair()
{
m_matcher.Append<TypesInitializer>({{"wheelchair", "no"}}, WheelchairAvailability::No);
m_matcher.Append<TypesInitializer>({{"wheelchair", "yes"}}, WheelchairAvailability::Yes);
m_matcher.Append<TypesInitializer>({{"wheelchair", "limited"}}, WheelchairAvailability::Limited);
}
};
enum class DrinkingWaterAvailability
{
No,
Yes,
};
class DrinkingWater : public TraitsBase<DrinkingWater, DrinkingWaterAvailability>
{
friend TraitsBase;
using TypesInitializer = std::initializer_list<std::initializer_list<char const *>>;
DrinkingWater()
{
m_matcher.Append<TypesInitializer>({{"drinking_water", "no"}}, DrinkingWaterAvailability::No);
m_matcher.Append<TypesInitializer>({{"drinking_water", "yes"}}, DrinkingWaterAvailability::Yes);
m_matcher.Append<TypesInitializer>({{"amenity", "drinking_water"}}, DrinkingWaterAvailability::Yes);
}
};
} // namespace ftraits