32 template<
class Key_,
class Val_,
class List_>
class MtMapElem;
39 template<
class... Pairs>
struct MtMap_ {
typedef MtMapTail type; };
40 template<
class Val,
class Key,
class... Pairs>
41 struct MtMap_<Val, Key, Pairs...> {
typedef MtMapElem<Key, Val,
typename MtMap_<Pairs...>::type> type; };
45 template<
class... Pairs>
using MtMap =
typename priv::MtMap_<Pairs...>::type;
49 template<
class Key_,
class Val_>
67 static mt_global(const Id, id, (#Name)); \
69 template<class Val> MtPair<Name, Val> operator=(Val&& val) \
70 { return MtPair<Name, Val>(forward<Val>(val)); } \
73 #define mtkeygen(Name) \
75 template<szt Index> struct Name \
77 static mt_global(const Id, id, (sout() << #Name << "<" << Index << ">")); \
78 template<class Val> MtPair<Name, Val> operator=(Val&& val) \
79 { return MtPair<Name, Val>(forward<Val>(val)); } \
85 template<
class... Pairs>
struct PairSeq {};
87 template<
class... Pairs>
struct PairSeqGen_ : PairSeqGen_<PairSeq<>, Pairs...> {};
88 template<
class... Seq,
class Key,
class Val,
class... Pairs>
89 struct PairSeqGen_<PairSeq<Seq...>, MtPair<Key, Val>, Pairs...> : PairSeqGen_<PairSeq<Seq..., Val, Key>, Pairs...> {};
90 template<
class... Seq>
91 struct PairSeqGen_<PairSeq<Seq...>> {
typedef PairSeq<Seq...> type; };
94 template<
class... Pairs>
using PairSeqGen =
typename PairSeqGen_<Pairs...>::type;
96 template<
class... Seq,
class... Pairs>
97 MtMap<Seq...> mtmap_(PairSeq<Seq...>, Pairs&&... pairs) {
return MtMap<Seq...>(mt::tag<0>(), forward<Pairs>(pairs)...); }
101 template<
class... Pairs>
104 decltype(priv::mtmap_(priv::PairSeqGen<Pairs...>(), forward<Pairs>(pairs)...))
105 {
return priv::mtmap_(priv::PairSeqGen<Pairs...>(), forward<Pairs>(pairs)...); }
112 template<
class Head,
class Elem = Head>
117 typedef typename Elem::Key Key;
118 typedef typename Elem::Val Val;
119 typedef typename Head::Super::template findElem<Key>::Next Next;
120 typedef typename Head::Super::template findElem<Key>::Prev Prev;
126 MtMapIter(Head& head) : _head(&head), pair(_head->get(Key())) {}
133 template<
class Iter>
bool operator==(
const Iter& rhs)
const {
return _head == rhs._head && std::is_same<typename Pair::Key, typename Iter::Pair::Key>::value; }
151 template<class Iter, class Func, typename std::enable_if<mt::isCallable<Func, typename Iter::Pair::Key, typename Iter::Pair::Val&>::value,
int>::type=0>
152 void for_each_mtmap_call(Iter& it, Func&& func) { func(it->key, it->val); }
153 template<class Iter, class Func, typename mt::disable_if<mt::isCallable<Func, typename Iter::Pair::Key, typename Iter::Pair::Val&>::value,
int>::type=0>
154 void for_each_mtmap_call(Iter&, Func&&) {}
157 template<
class Iter1,
class Iter2,
class Func>
159 typename mt::disable_if<!std::is_same<typename Iter1::Pair::Key, typename Iter2::Pair::Key>::value>::type {}
162 template<
class Iter1,
class Iter2,
class Func>
165 typename std::enable_if<!std::is_same<typename Iter1::Pair::Key, typename Iter2::Pair::Key>::value>::type
167 priv::for_each_mtmap_call(itBegin, func);
176 template<
class Val>
struct isOptional : std::false_type {};
177 template<
class Val>
struct isOptional<optional<Val>> : std::true_type {};
178 template<>
struct isOptional<mt::Void> : std::true_type {};
183 MtMapToString(ostream& os) : os(os), count(0) {}
184 template<
class Key,
class Val>
185 void operator()(Key,
const Val& val)
187 if (count++ > 0) os <<
", ";
188 os << Key::id() <<
": " << val;
196 template<
class Sub
class,
class Key_,
class Val_,
class List_>
209 static const bool isTail = std::is_same<List, mt::Void>::value;
212 template<
bool isTail, szt _=0>
216 template<
class Key,
class Prev>
220 template<
class Prev_>
229 template<szt Count>
struct sizeR : List::Super::template
sizeR<Count+1> {};
237 template<
class Key,
class Prev_>
246 template<szt Count>
struct sizeR :
mt::Value<szt, Count> {};
250 template<
class Key,
class Prev = Sub
class>
251 struct findElem : priv<isTail>::template findElem<Key, Prev> {};
255 struct sizeR : priv<isTail>::template sizeR<Count> {};
259 template<
class Key>
struct hasKey_ :
mt::Value<bool, !std::is_same<typename findElem<Key>::type, MtMapTail>::value> {};
261 template<
class Key>
bool hasKey(Key)
const {
return hasKey_<Key>::value; }
264 template<
class Key>
using getResult =
typename findElem<Key>::type::Val;
293 template<
class... Pairs>
struct insertResult_ {
typedef Subclass type; };
294 template<
class Val,
class Key,
class... Pairs>
295 struct insertResult_<Val, Key, Pairs...>
297 static_assert(!hasKey_<Key>::value,
"Insert failed. Key already exists.");
298 typedef MtMapElem<
Key,
Val,
typename insertResult_<Pairs...>::type> type;
301 template<
class PairSeq,
class... Pairs>
struct insertResult_seq;
302 template<
class... Seq,
class... Pairs>
303 struct insertResult_seq<
honey::priv::PairSeq<Seq...>, Pairs...> {
typedef typename insertResult_<Seq...>::type type; };
307 template<
class... Pairs>
using insertResult =
typename insertResult_<Pairs...>::type;
310 template<
class... Pairs>
311 typename insertResult_seq<honey::priv::PairSeqGen<Pairs...>, Pairs...>::type
312 insert(Pairs&&... pairs)
const {
return typename insertResult_seq<honey::priv::PairSeqGen<Pairs...>, Pairs...>::type(
mt::tag<1>(), subc(), forward<Pairs>(pairs)...); }
315 template<
bool isTail,
class... Keys>
318 typedef typename std::conditional<
320 typename List::Super::template eraseResult_<List::Super::isTail, Keys...>::type,
321 MtMapElem<
Key,
Val,
typename List::Super::template eraseResult_<List::Super::isTail, Keys...>::type>
324 template<
class... Keys>
325 struct eraseResult_<true, Keys...> {
typedef MtMapTail type; };
327 template<
class _=
void>
struct clearResult_ {
typedef MtMapTail type; };
331 template<
class... Keys>
using eraseResult =
typename eraseResult_<isTail, Keys...>::type;
334 template<
class... Keys>
335 eraseResult<Keys...>
erase(Keys...)
const {
return eraseResult<Keys...>(subc()); }
350 bool empty()
const {
return empty_::value; }
353 { os <<
"{ ";
for_each_mtmap(map.begin(), map.end(), honey::priv::MtMapToString(os)); os <<
" }";
return os; }
357 const Subclass& subc()
const {
return static_cast<const Subclass&
>(*this); }
358 Subclass& subc() {
return static_cast<Subclass&
>(*this); }
366 template<
class Key_,
class Val_,
class List_>
367 class MtMapElem :
public MtMapCommon<MtMapElem<Key_,Val_,List_>, Key_, Val_, List_>,
public List_
390 template<
class... Pairs>
using insertResult =
typename Super::template insertResult<Pairs...>;
392 template<
class... Keys>
using eraseResult =
typename Super::template eraseResult<Keys...>;
401 MtMapElem() { static_assert(honey::priv::isOptional<Val>::value,
"Key not optional. Must provide key to constructor."); }
404 template<
class Pair,
class... Pairs>
406 List(mt::tag<0>(), forward<Pairs>(pairs)...),
407 _val(forward<typename Pair::
Val>(pair.val))
408 { static_assert(std::is_same<Key,typename Pair::Key>::value,
"Ctor failed. Key mismatch. Wrong init order."); }
416 MtMapElem&
operator=(Map&& rhs) { priv<Map>::assign(_val, rhs.get(
Key())); List::operator=(forward<Map>(rhs));
return *
this; }
418 using List::operator[];
425 const Val&
get(
Key)
const {
return _val; }
435 void setDefaults(Map&& defaults) { priv<Map>::setDefault(_val, defaults.get(
Key())); List::setDefaults(forward<Map>(defaults)); }
444 static const bool optional = honey::priv::isOptional<Val>::value;
447 static auto init(T&& val) ->
typename std::enable_if<mt::True<T>::value && movable, decltype(move(val))>::type {
return move(val); }
449 static auto init(T&& val) ->
typename mt::disable_if<mt::True<T>::value && movable, T&>::type {
return val; }
450 static Val init(mt::Void)
452 static_assert(optional,
"Key not optional. Must provide key to constructor.");
457 static auto assign(
Val& lhs, T&& rhs) ->
typename std::enable_if<mt::True<T>::value && movable>::type { lhs = move(rhs); }
459 static auto assign(
Val& lhs, T&& rhs) ->
typename mt::disable_if<mt::True<T>::value && movable>::type { lhs = rhs; }
460 static void assign(
Val&, mt::Void){}
463 static auto setDefault(
Val& lhs, T&& rhs) ->
typename std::enable_if<mt::True<T>::value && optional>::type {
if (!lhs) lhs = rhs(); }
465 static auto setDefault(
Val&, T&&) ->
typename mt::disable_if<mt::True<T>::value && optional>::type {}
466 static void setDefault(
Val&, mt::Void) {}
470 template<
class Map,
class Pair,
class... Pairs>
471 MtMapElem(mt::tag<1>,
const Map&
map, Pair&& pair, Pairs&&... pairs) :
472 List(mt::tag<1>(), map, forward<Pairs>(pairs)...),
473 _val(forward<typename Pair::
Val>(pair.val)) {}
475 template<
class Map,
class Pair>
478 _val(forward<typename Pair::
Val>(pair.val)) {}
487 class MtMapElem<mt::Void, mt::Void, mt::Void> :
public MtMapCommon<MtMapTail, mt::Void, mt::Void, mt::Void>
489 template<
class,
class,
class,
class>
friend class MtMapCommon;
490 template<
class,
class,
class>
friend class MtMapElem;
491 template<
class,
class>
friend class MtMapIter;
492 typedef MtMapCommon<MtMapElem, Key, Val, List> Super;
504 template<
class Key>
Val get(
Key)
const {
return Val(); }
505 template<
class Key>
Val get(
Key) {
return Val(); }
507 template<
class Key,
class Val>
508 bool set(MtPair<Key, Val>&&) {
return false; }
Pair * operator->()
Definition: MtMap.h:139
beginResult_const begin() const
Definition: MtMap.h:272
MtMapElem(mt::tag< 0 >, Pair &&pair, Pairs &&...pairs)
Ctor, pairs must be in correct order.
Definition: MtMap.h:405
friend class MtMapCommon
Definition: MtMap.h:369
NextIter operator++()
Definition: MtMap.h:129
iterResult_const< Key > iter(Key) const
Definition: MtMap.h:290
Key_ Key
Key type.
Definition: MtMap.h:204
We don't have this key, recurse towards tail.
Definition: MtMap.h:217
typename findElem< Key >::type::Val getResult
Result type of get()
Definition: MtMap.h:264
MtMapElem & operator=(Map &&rhs)
Copy/Move-assign any map type. Assign to matching key in other map, recurse to tail.
Definition: MtMap.h:416
endResult end()
Get end of an iterator over keys and values of this map.
Definition: MtMap.h:279
friend ostream & operator<<(ostream &os, const Subclass &map)
Definition: MtMap.h:352
const Pair * operator->() const
Definition: MtMap.h:138
List Next
Definition: MtMap.h:225
clearResult_::type clearResult
Result type of clear()
Definition: MtMap.h:338
MtMapIter< Head, Prev > PrevIter
Definition: MtMap.h:130
typename Super::template hasKey_< Key > hasKey_
Definition: MtMap.h:378
Map element in recursive list.
Definition: MtMap.h:32
MtMapIter< const Subclass, MtMapTail > endResult_const
Definition: MtMap.h:276
Get size of map at compile-time.
Definition: MtMap.h:343
bool operator==(const Iter &rhs) const
Definition: MtMap.h:133
bool set(MtPair< Key, Val > &&pair)
Set value at key from the pair (key() = value). Returns false if the key isn't found.
Definition: MtMap.h:431
Prev_ Prev
Definition: MtMap.h:241
Val_ Val
Value type.
Definition: MtMap.h:205
iterResult< Key > iter(Key)
Get iterator to element by key.
Definition: MtMap.h:288
szt size() const
Get size of map.
Definition: MtMap.h:345
const Val & get(Key) const
Get value at key.
Definition: MtMap.h:425
Subclass type
Definition: MtMap.h:240
Key_ Key
Definition: MtMap.h:52
Val & operator[](Key)
Definition: MtMap.h:421
static auto _
Definition: Module.cpp:8
Val_ Val
Definition: MtMap.h:53
MtPair(Val &&val)
Definition: MtMap.h:56
beginResult begin()
Get beginning of an iterator over keys and values of this map.
Definition: MtMap.h:271
Bidirectional iterator over map key/value pairs.
Definition: MtMap.h:113
bool empty() const
Check if empty.
Definition: MtMap.h:350
typename insertResult_< Pairs... >::type insertResult
Result type of insert(). New pairs are inserted at the front.
Definition: MtMap.h:307
auto mtmap(Pairs &&...pairs) -> decltype(priv::mtmap_(priv::PairSeqGen< Pairs... >(), forward< Pairs >(pairs)...))
Construct a map from (key() = value) pairs.
Definition: MtMap.h:103
typename eraseResult_< isTail, Keys... >::type eraseResult
Result type of erase(). Reconstructs type without matching keys.
Definition: MtMap.h:331
Pair & operator*()
Definition: MtMap.h:137
auto for_each_mtmap(Iter1 itBegin, Iter2 itEnd, Func &&func) -> typename std::enable_if<!std::is_same< typename Iter1::Pair::Key, typename Iter2::Pair::Key >::value >::type
Iterate over map calling functor (visitor) for each key/value pair.
Definition: MtMap.h:164
MtMapIter< Head, Next > NextIter
Definition: MtMap.h:128
MtMapIter(Head &head)
Definition: MtMap.h:126
MtMapElem()
Definition: MtMap.h:401
MtMapIter< Subclass, MtMapTail > endResult
Result type of end()
Definition: MtMap.h:275
Val val
Definition: MtMap.h:59
const Val & operator[](Key) const
Get value at key.
Definition: MtMap.h:420
typename Super::template insertResult< Pairs... > insertResult
Definition: MtMap.h:390
Subclass Next
Definition: MtMap.h:242
Recurse to tail.
Definition: MtMap.h:229
MtMapIter< const Subclass > beginResult_const
Definition: MtMap.h:268
List_ List
Rest of map.
Definition: MtMap.h:206
Use to differentiate an overloaded function by type. Accepts dummy parameter default value: func(tag<...
Definition: Meta.h:39
size_t szt
Size type, shorthand for size_t.
Definition: Core.h:90
Enables any type to be optional so it can exist in an uninitialized null state.
Definition: Optional.h:52
typename Super::template iterResult< Key > iterResult
Definition: MtMap.h:387
Prev_ Prev
Definition: MtMap.h:224
Key/value pair. A pair can be constructed with the syntax: (key() = value)
Definition: MtMap.h:50
List_ List
Rest of map.
Definition: MtMap.h:206
insertResult_seq< honey::priv::PairSeqGen< Pairs... >, Pairs... >::type insert(Pairs &&...pairs) const
Insert pairs of the form (key() = value) into the map.
Definition: MtMap.h:312
endResult_const end() const
Definition: MtMap.h:280
const Key key
Definition: MtMap.h:58
Common functions between map elem and the map tail specialization. Use through class MtMapElem...
Definition: MtMap.h:198
clearResult clear()
Clear map of all keys.
Definition: MtMap.h:340
MtMapElem(Map &&map)
Copy/Move any map type. Init with matching key in other map, recurse to tail.
Definition: MtMap.h:412
MtPair< Key, decltype(declval< Head >).get(Key()))> Pair
Definition: MtMap.h:124
const Pair & operator*() const
Definition: MtMap.h:136
MtMapIter< Subclass > beginResult
Result type of begin()
Definition: MtMap.h:267
eraseResult< Keys... > erase(Keys...) const
Erase keys from the map.
Definition: MtMap.h:335
typename Super::template eraseResult< Keys... > eraseResult
Definition: MtMap.h:392
Check if key exists at compile-time.
Definition: MtMap.h:259
bool hasKey(Key) const
Check if has key.
Definition: MtMap.h:261
Key_ Key
Key type.
Definition: MtMap.h:204
PrevIter operator--()
Definition: MtMap.h:131
void setDefaults(Map &&defaults)
Set any uninitialized optional values to the defaults provided. A default for a key must be a functor...
Definition: MtMap.h:435
bool operator!=(const Iter &rhs) const
Definition: MtMap.h:134
Check if empty at compile-time.
Definition: MtMap.h:348
Global Honeycomb namespace.
typename Super::template getResult< Key > getResult
Definition: MtMap.h:380
MtMapElem< mt::Void, mt::Void, mt::Void > MtMapTail
Tail of map list.
Definition: MtMap.h:32
friend class MtMapIter
Definition: MtMap.h:371
Subclass type
Definition: MtMap.h:223
typename priv::MtMap_< Pairs... >::type MtMap
Declare a map type with MtMap
Definition: MtMap.h:46
typename Super::template iterResult_const< Key > iterResult_const
Definition: MtMap.h:388
Val_ Val
Value type.
Definition: MtMap.h:205
OutSeq && map(Range &&, Seqs &&..., OutSeq &&, Func &&)
Transform a series of sequences into an output.