$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 #pragma once
23 
24 #include <vector> // for vector<>
25 
26 #include <boost/algorithm/string/join.hpp> // for boost::algorithm::join
27 #include <boost/assign/list_of.hpp> // for list_of
28 #include <boost/bimap.hpp> // for bimap
29 #include <boost/range/adaptor/map.hpp> // for boost::adaptors::map
30 #include <boost/range/algorithm/copy.hpp> // for boost::algorithm::copy
31 
32 namespace cloe {
33 
35 template <typename Type1, typename Type2, typename CRTP>
36 class BimapBase1 {
37  public:
38  typedef Type1 type1;
39  typedef Type2 type2;
40  typedef boost::bimap<Type1, Type2> bm_type;
41  static const typename bm_type::left_map& left() { return CRTP::map_.left; }
42  static const typename bm_type::right_map& right() { return CRTP::map_.right; }
43  static typename bm_type::left_const_iterator beginLeft() { return CRTP::map_.left.begin(); }
44  static typename bm_type::left_const_iterator endLeft() { return CRTP::map_.left.end(); }
45  static typename bm_type::left_const_iterator findLeft(const type1& rhs) {
46  return CRTP::map_.left.find(rhs);
47  }
48  static typename bm_type::right_const_iterator beginRight() { return CRTP::map_.right.begin(); }
49  static typename bm_type::right_const_iterator endRight() { return CRTP::map_.right.end(); }
50  static typename bm_type::right_const_iterator findRight(const type2& rhs) {
51  return CRTP::map_.right.find(rhs);
52  }
53 };
54 
61 template <typename Type1, typename Type2, typename CRTP>
62 class BimapBase2 : public BimapBase1<Type1, Type2, CRTP> {
63  public:
65  typedef typename base::bm_type bm_type;
66  typedef typename base::type1 type1;
67  typedef typename base::type2 type2;
68 
70  static auto beginImpl(const Type1* = nullptr) -> decltype(base::beginLeft()) {
71  return base::beginLeft();
72  }
74  static auto beginImpl(const Type2* = nullptr) -> decltype(base::beginRight()) {
75  return base::beginRight();
76  }
78  template <typename T>
79  static auto begin() -> decltype(beginImpl((T*)nullptr)) {
80  return beginImpl((T*)nullptr);
81  }
83  static auto endImpl(const Type1* = nullptr) -> decltype(base::endLeft()) {
84  return base::endLeft();
85  }
87  static auto endImpl(const Type2* = nullptr) -> decltype(base::endRight()) {
88  return base::endRight();
89  }
91  template <typename T>
92  static auto end() -> decltype(endImpl((T*)nullptr)) {
93  return endImpl((T*)nullptr);
94  }
95 
97  static auto findImpl(const type1& item) -> decltype(base::findLeft(item)) {
98  return base::findLeft(item);
99  }
101  static auto findImpl(const type2& item) -> decltype(base::findRight(item)) {
102  return base::findRight(item);
103  }
105  template <typename T>
106  static auto find(const T& item) -> decltype(findImpl(item)) {
107  return findImpl(item);
108  }
109 };
110 
112 // template <typename Type, typename CRTP>
113 // class BimapBase2<Type, Type, CRTP> : public std::string {};
114 //BimapBase1<Type, Type, CRTP> {};
115 
117 template <typename Type1, typename Type2>
118 class Bimap : public BimapBase2<Type1, Type2, Bimap<Type1, Type2>> {
119  public:
120  typedef Type1 type1;
121  typedef Type2 type2;
122  typedef boost::bimap<type1, type2> bm_type;
123 
124  private:
125  static const bm_type map_;
126  template <typename Type3, typename Type4, typename CRTP2>
127  friend class BimapBase2;
128  template <typename Type3, typename Type4, typename CRTP2>
129  friend class BimapBase1;
130 };
131 
133 template <typename Type>
134 class Bimap<Type, Type> : public BimapBase2<Type, Type, Bimap<Type, Type>> {
135  public:
136  typedef Type type1;
137  typedef Type type2;
138  typedef boost::bimap<type1, type2> bm_type;
139 
140  private:
141  static const bm_type map_;
142  template <typename Type1, typename Type2, typename CRTP>
143  friend class BimapBase2;
144  template <typename Type1, typename Type2, typename CRTP>
145  friend class BimapBase1;
146 };
147 
148 template <typename TEnum>
149 class EnumStringMap : public BimapBase2<TEnum, std::string, EnumStringMap<TEnum>> {
150  public:
152  typedef typename base::bm_type bm_type;
153  typedef typename base::type1 type1;
154  typedef typename base::type2 type2;
155 
156  private:
157  static const bm_type map_;
158  template <typename Type1, typename Type2, typename CRTP>
159  friend class BimapBase2;
160  template <typename Type1, typename Type2, typename CRTP>
161  friend class BimapBase1;
162 };
163 template <>
164 class EnumStringMap<std::string> {};
165 
166 #define IMPLEMENT_ENUMSTRINGMAP(ENUMSTRINGMAPTYPE) \
167  template <> \
168  const EnumStringMap<ENUMSTRINGMAPTYPE>::bm_type EnumStringMap<ENUMSTRINGMAPTYPE>::map_ = \
169  boost::assign::list_of<EnumStringMap<ENUMSTRINGMAPTYPE>::bm_type::relation>
170 
171 } // namespace cloe
BimapBase1 implements basic functions.
Definition: bimap.hpp:36
Definition: bimap.hpp:62
static auto find(const T &item) -> decltype(findImpl(item))
map::find()
Definition: bimap.hpp:106
static auto beginImpl(const Type1 *=nullptr) -> decltype(base::beginLeft())
Implementation of begin() for the left-map.
Definition: bimap.hpp:70
static auto end() -> decltype(endImpl((T *) nullptr))
map::end()
Definition: bimap.hpp:92
static auto endImpl(const Type1 *=nullptr) -> decltype(base::endLeft())
Implementation of end() for the left-map.
Definition: bimap.hpp:83
static auto findImpl(const type2 &item) -> decltype(base::findRight(item))
Implementation of find() for right-map.
Definition: bimap.hpp:101
static auto beginImpl(const Type2 *=nullptr) -> decltype(base::beginRight())
Implementation of begin() for the right-map.
Definition: bimap.hpp:74
static auto findImpl(const type1 &item) -> decltype(base::findLeft(item))
Implementation of find() for left-map.
Definition: bimap.hpp:97
static auto endImpl(const Type2 *=nullptr) -> decltype(base::endRight())
Implementation of end() for the right-map.
Definition: bimap.hpp:87
static auto begin() -> decltype(beginImpl((T *) nullptr))
Derivate of map::begin()
Definition: bimap.hpp:79
BimapBase class for a pair of identical types, which will get derived further.
Definition: bimap.hpp:118
Definition: bimap.hpp:149