1 /*
2  * Copyright 2014 Google Inc. All rights reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef FRUIT_META_IMMUTABLE_MAP_H
18 #define FRUIT_META_IMMUTABLE_MAP_H
19 
20 #include <fruit/impl/meta/basics.h>
21 #include <fruit/impl/meta/immutable_set.h>
22 #include <fruit/impl/meta/pair.h>
23 #include <fruit/impl/meta/set.h>
24 
25 namespace fruit {
26 namespace impl {
27 namespace meta {
28 
29 // ImmutableMap ::= ImmutableSet<Pair<Key1, Value1>, ..., Pair<KeyN, ValueN>>
30 
31 struct VectorsToImmutableMap {
32   template <typename KeyVector, typename ValueVector>
33   struct apply;
34 
35   template <typename... Keys, typename... Values>
36   struct apply<Vector<Keys...>, Vector<Values...>> {
37     using type = ConsImmutableSet<Pair<Keys, Values>...>;
38   };
39 };
40 
41 struct VectorToImmutableMap {
42   template <typename PairVector>
43   struct apply;
44 
45   template <typename... Pairs>
46   struct apply<Vector<Pairs...>> {
47     using type = ConsImmutableSet<Pairs...>;
48   };
49 };
50 
51 struct IsInImmutableMap {
52   template <typename S, typename T>
53   struct apply {
54     using type = Bool<std::is_base_of<T, S>::value>;
55   };
56 };
57 
58 struct FindInImmutableMap {
59   template <typename M, typename T>
60   struct apply {
61     template <typename Value>
62     static Value f(Pair<T, Value>*);
63 
64     static None f(void*);
65 
66     using type = decltype(f((M*)nullptr));
67   };
68 };
69 
70 struct ImmutableMapContainsKey {
71   template <typename M, typename T>
72   struct apply {
73     using type = Not(IsNone(FindInImmutableMap(M, T)));
74   };
75 };
76 
77 struct GetImmutableMapKeys {
78   template <typename M>
79   struct apply;
80 
81   template <typename... Pairs>
82   struct apply<ConsImmutableSet<Pairs...>> {
83     using type = Vector<typename Pairs::First...>;
84   };
85 };
86 
87 } // namespace meta
88 } // namespace impl
89 } // namespace fruit
90 
91 #endif // FRUIT_META_IMMUTABLE_MAP_H
92