$darkmode
bimap.hpp
Go to the documentation of this file.
1 /*
2  * Copyright 2020 Robert Bosch GmbH
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  * SPDX-License-Identifier: Apache-2.0
17  */
22 #include <vector> // for vector<>
23 
24 #include <boost/algorithm/string/join.hpp> // for boost::algorithm::join
25 #include <boost/assign/list_of.hpp> // for list_of
26 #include <boost/bimap.hpp> // for bimap
27 #include <boost/range/adaptor/map.hpp> // for boost::adaptors::map
28 #include <boost/range/algorithm/copy.hpp> // for boost::algorithm::copy
29 
30 namespace cloe {
31 
33 template <typename Type1, typename Type2, typename CRTP>
34 class BimapBase1 {
35  public:
36  typedef Type1 type1;
37  typedef Type2 type2;
38  typedef boost::bimap<Type1, Type2> bm_type;
39  static const typename bm_type::left_map& left() { return CRTP::map_.left; }
40  static const typename bm_type::right_map& right() { return CRTP::map_.right; }
41  static typename bm_type::left_const_iterator beginLeft() { return CRTP::map_.left.begin(); }
42  static typename bm_type::left_const_iterator endLeft() { return CRTP::map_.left.end(); }
43  static typename bm_type::left_const_iterator findLeft(const type1& rhs) {
44  return CRTP::map_.left.find(rhs);
45  }
46  static typename bm_type::right_const_iterator beginRight() { return CRTP::map_.right.begin(); }
47  static typename bm_type::right_const_iterator endRight() { return CRTP::map_.right.end(); }
48  static typename bm_type::right_const_iterator findRight(const type2& rhs) {
49  return CRTP::map_.right.find(rhs);
50  }
51 };
52 
59 template <typename Type1, typename Type2, typename CRTP>
60 class BimapBase2 : public BimapBase1<Type1, Type2, CRTP> {
61  public:
63  typedef typename base::bm_type bm_type;
64  typedef typename base::type1 type1;
65  typedef typename base::type2 type2;
66 
68  static auto beginImpl(const Type1* = nullptr) -> decltype(base::beginLeft()) {
69  return base::beginLeft();
70  }
72  static auto beginImpl(const Type2* = nullptr) -> decltype(base::beginRight()) {
73  return base::beginRight();
74  }
76  template <typename T>
77  static auto begin() -> decltype(beginImpl((T*)nullptr)) {
78  return beginImpl((T*)nullptr);
79  }
81  static auto endImpl(const Type1* = nullptr) -> decltype(base::endLeft()) {
82  return base::endLeft();
83  }
85  static auto endImpl(const Type2* = nullptr) -> decltype(base::endRight()) {
86  return base::endRight();
87  }
89  template <typename T>
90  static auto end() -> decltype(endImpl((T*)nullptr)) {
91  return endImpl((T*)nullptr);
92  }
93 
95  static auto findImpl(const type1& item) -> decltype(base::findLeft(item)) {
96  return base::findLeft(item);
97  }
99  static auto findImpl(const type2& item) -> decltype(base::findRight(item)) {
100  return base::findRight(item);
101  }
103  template <typename T>
104  static auto find(const T& item) -> decltype(findImpl(item)) {
105  return findImpl(item);
106  }
107 };
108 
110 // template <typename Type, typename CRTP>
111 // class BimapBase2<Type, Type, CRTP> : public std::string {};
112 //BimapBase1<Type, Type, CRTP> {};
113 
115 template <typename Type1, typename Type2>
116 class Bimap : public BimapBase2<Type1, Type2, Bimap<Type1, Type2>> {
117  public:
118  typedef Type1 type1;
119  typedef Type2 type2;
120  typedef boost::bimap<type1, type2> bm_type;
121 
122  private:
123  static const bm_type map_;
124  template <typename Type3, typename Type4, typename CRTP2>
125  friend class BimapBase2;
126  template <typename Type3, typename Type4, typename CRTP2>
127  friend class BimapBase1;
128 };
129 
131 template <typename Type>
132 class Bimap<Type, Type> : public BimapBase2<Type, Type, Bimap<Type, Type>> {
133  public:
134  typedef Type type1;
135  typedef Type type2;
136  typedef boost::bimap<type1, type2> bm_type;
137 
138  private:
139  static const bm_type map_;
140  template <typename Type1, typename Type2, typename CRTP>
141  friend class BimapBase2;
142  template <typename Type1, typename Type2, typename CRTP>
143  friend class BimapBase1;
144 };
145 
146 template <typename TEnum>
147 class EnumStringMap : public BimapBase2<TEnum, std::string, EnumStringMap<TEnum>> {
148  public:
150  typedef typename base::bm_type bm_type;
151  typedef typename base::type1 type1;
152  typedef typename base::type2 type2;
153 
154  private:
155  static const bm_type map_;
156  template <typename Type1, typename Type2, typename CRTP>
157  friend class BimapBase2;
158  template <typename Type1, typename Type2, typename CRTP>
159  friend class BimapBase1;
160 };
161 template <>
162 class EnumStringMap<std::string> {};
163 
164 #define IMPLEMENT_ENUMSTRINGMAP(ENUMSTRINGMAPTYPE) \
165  template <> \
166  const EnumStringMap<ENUMSTRINGMAPTYPE>::bm_type EnumStringMap<ENUMSTRINGMAPTYPE>::map_ = \
167  boost::assign::list_of<EnumStringMap<ENUMSTRINGMAPTYPE>::bm_type::relation>
168 
169 } // namespace cloe
BimapBase1 implements basic functions.
Definition: bimap.hpp:34
Definition: bimap.hpp:60
static auto find(const T &item) -> decltype(findImpl(item))
map::find()
Definition: bimap.hpp:104
static auto beginImpl(const Type1 *=nullptr) -> decltype(base::beginLeft())
Implementation of begin() for the left-map.
Definition: bimap.hpp:68
static auto end() -> decltype(endImpl((T *) nullptr))
map::end()
Definition: bimap.hpp:90
static auto endImpl(const Type1 *=nullptr) -> decltype(base::endLeft())
Implementation of end() for the left-map.
Definition: bimap.hpp:81
static auto findImpl(const type2 &item) -> decltype(base::findRight(item))
Implementation of find() for right-map.
Definition: bimap.hpp:99
static auto beginImpl(const Type2 *=nullptr) -> decltype(base::beginRight())
Implementation of begin() for the right-map.
Definition: bimap.hpp:72
static auto findImpl(const type1 &item) -> decltype(base::findLeft(item))
Implementation of find() for left-map.
Definition: bimap.hpp:95
static auto endImpl(const Type2 *=nullptr) -> decltype(base::endRight())
Implementation of end() for the right-map.
Definition: bimap.hpp:85
static auto begin() -> decltype(beginImpl((T *) nullptr))
Derivate of map::begin()
Definition: bimap.hpp:77
BimapBase class for a pair of identical types, which will get derived further.
Definition: bimap.hpp:116
Definition: bimap.hpp:147