SMT-RAT  24.02
Toolbox for Strategic and Parallel Satisfiability-Modulo-Theories Solving
VariantMap.h
Go to the documentation of this file.
1 /**
2  * @file VariantMap.h
3  * @author Gereon Kremer <gereon.kremer@cs.rwth-aachen.de>
4  */
5 
6 #pragma once
7 
9 
10 #ifdef __VS
11 #pragma warning(push, 0)
12 #include <boost/variant.hpp>
13 #pragma warning(pop)
14 #else
15 #include <boost/variant.hpp>
16 #include <cxxabi.h>
17 #endif
18 
19 #include <map>
20 #include <string>
21 #include <cstdlib>
22 
23 namespace smtrat {
24 
25 /**
26  * States whether a given type is a `boost::variant`.
27  * By default, a type is not.
28  */
29 template <class T> struct is_variant : std::false_type {};
30 /**
31  * States that `boost::variant` is indeed a `boost::variant`.
32  */
33 template <BOOST_VARIANT_ENUM_PARAMS(typename U)> struct is_variant<boost::variant<BOOST_VARIANT_ENUM_PARAMS(U)>> : std::true_type {};
34 /**
35  * States that `const boost::variant` is indeed a `boost::variant`.
36  */
37 template <BOOST_VARIANT_ENUM_PARAMS(typename U)> struct is_variant<const boost::variant<BOOST_VARIANT_ENUM_PARAMS(U)>> : std::true_type {};
38 
39 /**
40  * This class is a specialization of `std::map` where the keys are of arbitrary type and the values are of type `boost::variant`.
41  *
42  * There is no point in using this class if the values are no variants.
43  * Most probably, it would not compile anyway and fail to do so with a large bunch of compiler errors.
44  * To prevent this, we assert that the value type is indeed a `boost::variant`.
45  *
46  * Additionally to the standard methods inherited from `std::map`, it implements three additional methods:
47  * - `assertType<T>(key, out)`: Asserts that there is a value for the given key and that it has the type `T`. If this is not the case, an appropriate error is written to `out`.
48  * - `has<T>(key)`: Checks if there is a value for the given key and if this value has the type `T`.
49  * - `get<T>(key)`: Returns the value for the given key as type `T`.
50  *
51  * @tparam Key Type of keys.
52  * @tparam Value Type of values.
53  */
54 template<typename Key, typename Value>
55 class VariantMap : public std::map<Key, Value> {
56  /// Asserts that the value type is a variant.
57  static_assert(is_variant<Value>::value, "VariantMap is designed for Values of type boost::variant only.");
58 private:
59  /**
60  * Converts a type string from `typeid` to a human-readable representation.
61  * This function makes use of `abi::__cxa_demangle`.
62  * @param t A type string obtained from `typeid`.
63  * @return Demangled type string.
64  */
65  std::string demangle(const char* t) const {
66 #ifdef __VS
67  //TODO find windows specific solution
68  std::string type(t);
69 #else
70  int status;
71  char* res = abi::__cxa_demangle(t, 0, 0, &status);
72  std::string type(res);
73  std::free(res);
74 #endif
75  return type;
76  }
77 public:
78  /**
79  * Asserts that the value that is associated with the given key has a specified type.
80  *
81  * The assertion holds, if
82  * - there is a value in the map for the given key and
83  * - the stored value has the type `T`.
84  * @tparam T Type that the value should have.
85  * @tparam Output Type of out.
86  * @param key Key.
87  * @param out Functor returning an output stream.
88  */
89  template<typename T, typename Output>
90  void assertType(const Key& key, Output out) const {
91  auto it = this->find(key);
92  if (it == this->end()) {
93  out() << "No value was set for " << key << ".";
94  assert(it != this->end());
95  } else if (boost::get<T>(&(it->second)) == nullptr) {
96  out() << "The type of " << key << " should be '" << demangle(typeid(T).name()) << "' but is '" << demangle(it->second.type().name()) << "'.";
97  assert(boost::get<T>(&(it->second)) != nullptr);
98  }
99  }
100 
101  /**
102  * Checks if there is a value of the specified type for the given key.
103  * @tparam T Type that the value should have.
104  * @param key Key.
105  * @return If there is a value of this type.
106  */
107  template<typename T>
108  bool has(const Key& key) const {
109  auto it = this->find(key);
110  if (it == this->end()) return false;
111  return boost::get<T>(&(it->second)) != nullptr;
112  }
113  /**
114  * Returns the value associated with the given key as type `T`.
115  * @tparam T Type of the value.
116  * @param key Key.
117  * @return Value of key as type `T`.
118  */
119  template<typename T>
120  const T& get(const Key& key) const {
121  auto it = this->find(key);
122  return boost::get<T>(it->second);
123  }
124 };
125 
126 }
This class is a specialization of std::map where the keys are of arbitrary type and the values are of...
Definition: VariantMap.h:55
const T & get(const Key &key) const
Returns the value associated with the given key as type T.
Definition: VariantMap.h:120
bool has(const Key &key) const
Checks if there is a value of the specified type for the given key.
Definition: VariantMap.h:108
void assertType(const Key &key, Output out) const
Asserts that the value that is associated with the given key has a specified type.
Definition: VariantMap.h:90
std::string demangle(const char *t) const
Asserts that the value type is a variant.
Definition: VariantMap.h:65
static bool find(V &ts, const T &t)
Definition: Alg.h:47
QuantifierType type(const std::pair< QuantifierType, std::vector< carl::Variable >> &p)
Definition: QEQuery.h:39
Class to create the formulas for axioms.
States whether a given type is a boost::variant.
Definition: VariantMap.h:29