i6engine  1.0
attributeMap.h
Go to the documentation of this file.
1 /*
2  * i6engine
3  * Copyright (2016) Daniel Bonrath, Michael Baer, All rights reserved.
4  *
5  * This file is part of i6engine; i6engine is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18  */
19 
25 #ifndef __I6ENGINE_API_CONFIGS_ATTRIBUTEMAP_H__
26 #define __I6ENGINE_API_CONFIGS_ATTRIBUTEMAP_H__
27 
28 #include <map>
29 #include <string>
30 #include <type_traits>
31 
33 
34 #include "boost/lexical_cast.hpp"
35 
36 #include "boost/archive/text_iarchive.hpp"
37 #include "boost/archive/text_oarchive.hpp"
38 
39 namespace i6e {
40 namespace api {
41 
42  typedef std::map<std::string, std::string> attributeMap;
43 
44 namespace detail {
45 
46  template<typename T>
47  struct hasInsertInMap {
48  template<typename U, void(U::*)(const std::string &, attributeMap &)const>
49  struct SFINAE {
50  };
51  template<typename U>
52  static char Test(SFINAE<U, &U::insertInMap>*);
53  template<typename U>
54  static int Test(...);
55  static const bool value = sizeof(Test<T>(0)) == sizeof(char);
56  };
57 
58  template<class type, class...Args>
60  template<class C>
61  static C arg();
62 
63  template<typename U>
64  static char constructible_test(U *, decltype(U(arg<Args>()...)) * = 0);
65  static int constructible_test(...);
66 
67  static const bool value = sizeof(decltype(constructible_test(static_cast<type *>(nullptr)))) == sizeof(char);
68  };
69 
70 } /* namespace detail */
71 
75  template<typename T>
76  typename std::enable_if<std::is_enum<T>::value && !std::is_fundamental<T>::value, void>::type parseAttribute(attributeMap::const_iterator it, T & value) {
77  value = T(std::stoul(it->second));
78  }
79 
83  template<typename T>
84  typename std::enable_if<!std::is_enum<T>::value && !std::is_fundamental<T>::value && detail::constructible_from<T, const std::string &>::value, void>::type parseAttribute(attributeMap::const_iterator it, T & value) {
85  value = T(it->second);
86  }
87 
91  template<typename T>
92  typename std::enable_if<!std::is_enum<T>::value && !std::is_fundamental<T>::value && !detail::constructible_from<T, const std::string &>::value, void>::type parseAttribute(attributeMap::const_iterator it, T & value) {
93  std::stringstream ss(it->second);
94  boost::archive::text_iarchive arch(ss, boost::archive::no_header | boost::archive::no_codecvt | boost::archive::no_xml_tag_checking | boost::archive::archive_flags::no_tracking);
95  arch >> value;
96  }
97 
101  template<typename T>
102  typename std::enable_if<!std::is_enum<T>::value && std::is_fundamental<T>::value, void>::type parseAttribute(attributeMap::const_iterator it, T & value) {
103  value = boost::lexical_cast<T>(it->second);
104  }
105 
109  template<typename T>
110  typename std::enable_if<std::is_enum<T>::value && !std::is_fundamental<T>::value, void>::type writeAttribute(attributeMap & params, const std::string & entry, const T & value) {
111  params.insert(std::make_pair(entry, std::to_string(int(value))));
112  }
113 
117  template<bool Required, typename T>
118  typename std::enable_if<Required, void>::type parseAttribute(const attributeMap & params, const std::string & entry, T & value) {
119  auto it = params.find(entry);
120  if (it == params.end()) {
121  ISIXE_THROW_API("parseAttribute", entry + " not set!");
122  } else {
123  parseAttribute(it, value);
124  }
125  }
126 
130  template<bool Required, typename T>
131  typename std::enable_if<!Required, void>::type parseAttribute(const attributeMap & params, const std::string & entry, T & value) {
132  auto it = params.find(entry);
133  if (it != params.end()) {
134  parseAttribute(it, value);
135  }
136  }
137 
141  template<typename T>
142  typename std::enable_if<!std::is_enum<T>::value && !std::is_fundamental<T>::value && !std::is_same<T, std::string>::value && detail::hasInsertInMap<T>::value, void>::type writeAttribute(attributeMap & params, const std::string & entry, T value) {
143  value.insertInMap(entry, params);
144  }
145 
149  template<typename T>
150  typename std::enable_if<!std::is_enum<T>::value && !std::is_fundamental<T>::value && (std::is_same<T, std::string>::value || std::is_same<const char, typename std::remove_pointer<T>::type>::value), void>::type writeAttribute(attributeMap & params, const std::string & entry, T value) {
151  params.insert(std::make_pair(entry, value));
152  }
153 
157  template<typename T>
158  typename std::enable_if<!std::is_enum<T>::value && std::is_fundamental<T>::value, void>::type writeAttribute(attributeMap & params, const std::string & entry, T value) {
159  writeAttribute(params, entry, std::to_string(value));
160  }
161 
165  template<typename T>
166  typename std::enable_if<!std::is_enum<T>::value && !std::is_fundamental<T>::value && !std::is_same<T, std::string>::value && !std::is_same<const char, typename std::remove_pointer<T>::type>::value && !detail::hasInsertInMap<T>::value, void>::type writeAttribute(attributeMap & params, const std::string & entry, T value) {
167  std::stringstream ss;
168  boost::archive::text_oarchive arch(ss, boost::archive::no_header | boost::archive::no_codecvt | boost::archive::no_xml_tag_checking | boost::archive::archive_flags::no_tracking);
169  arch << value;
170  writeAttribute(params, entry, ss.str());
171  }
172 
173 } /* namespace api */
174 } /* namespace i6e */
175 
176 #endif /* __I6ENGINE_API_CONFIGS_ATTRIBUTEMAP_H__ */
177 
static char Test(SFINAE< U,&U::insertInMap > *)
#define ISIXE_THROW_API(module, message)
Definition: Exceptions.h:45
std::map< std::string, std::string > attributeMap
Definition: attributeMap.h:42
std::enable_if< std::is_enum< T >::value &&!std::is_fundamental< T >::value, void >::type parseAttribute(attributeMap::const_iterator it, T &value)
converts a string to enum value
Definition: attributeMap.h:76
std::enable_if< std::is_enum< T >::value &&!std::is_fundamental< T >::value, void >::type writeAttribute(attributeMap &params, const std::string &entry, const T &value)
writes into an attributeMap
Definition: attributeMap.h:110
static char constructible_test(U *, decltype(U(arg< Args >()...))*=0)