9#include <boost/mpl/for_each.hpp>
10#include <boost/tokenizer.hpp>
12#include <boost/variant.hpp>
13#include <boost/foreach.hpp>
14#include <boost/mpl/vector.hpp>
15#include <boost/mpl/insert_range.hpp>
16#include <boost/static_assert.hpp>
30 #define MAKE_VARIANT_OVER(...) \
31 typedef boost::mpl::vector<__VA_ARGS__> VectorofTypes; \
32 typedef boost::make_variant_over<VectorofTypes>::type ValueVar; \
33 static const std::string type_names = #__VA_ARGS__;
50 MAKE_VARIANT_OVER(
bool,
59 std::vector<uint32_t>,
61 std::vector<uint64_t>,
63 std::vector<std::string>)
66 typedef std::map<std::string, std::string> TypeToTypeNameMap;
106 const std::string & desc=
"") :
107 key_(key), value_(val), desc_(desc)
160 return boost::get<T>(value_);
162 catch(
const boost::bad_get & e) {
163 std::string whatitis =
"unknown";
164 std::string whatyouwanted =
"unknown";
165 TypeToTypeNameMap::const_iterator it =
GBL_type_name_map.find(value_.type().name());
167 whatitis = (*it).second;
171 whatyouwanted = (*it).second;
173 std::cerr <<
"ERROR: Attempt to get a '" << whatyouwanted
174 <<
"' (" <<
typeid(T).name() <<
") type on KeyValue '"
175 << key_ <<
"' that's a '" << whatitis <<
"'" << std::endl;
207 return getValue<T>();
215 template <
typename T>
230 template <
typename T>
236 SpartaException e(
"Could not get compiler-independent type name for \"");
237 e <<
typeid(T).name() <<
"\". Valid type keys are:";
239 e <<
" " << p.first <<
":" << p.second <<
" ";
248 template <
typename T>
249 const std::string& operator()(
const T&)
const {
return lookupTypeName<T>(); }
281 return boost::get<T&>(value_);
283 catch(
const boost::bad_get & e) {
284 throw throwBadGet_<T>(e);
296 return boost::get<const T&>(value_);
298 catch(
const boost::bad_get & e) {
299 throw throwBadGet_<T>(e);
317 const boost::bad_get& throwBadGet_(
const boost::bad_get& e)
const {
318 std::string whatitis =
"unknown";
319 std::string whatyouwanted =
"unknown";
320 TypeToTypeNameMap::const_iterator it =
GBL_type_name_map.find(value_.type().name());
322 whatitis = (*it).second;
326 whatyouwanted = (*it).second;
328 std::cerr <<
"ERROR: Attempt to get a '" << whatyouwanted
329 <<
"' (" <<
typeid(T).name() <<
") type on KeyValue '"
330 << key_ <<
"' that's a '" << whatitis <<
"'" << std::endl;
334 const std::string key_;
343#define SPARTA_KVPAIR_BODY \
348 template<class type> \
349 void operator()(type) { \
350 assert(current_type_ != tok_.end()); \
351 KeyValue::GBL_type_name_map[typeid(type).name()] = boost::trim_left_copy(*current_type_); \
355 NameMapper() : tok_(type_names, boost::char_separator<char>(",")) \
357 current_type_ = tok_.begin(); \
358 boost::mpl::for_each<ValueVar::types>(*this); \
362 boost::tokenizer<boost::char_separator<char> >::iterator current_type_; \
363 boost::tokenizer<boost::char_separator<char> > tok_; \
366 TypeToTypeNameMap KeyValue::GBL_type_name_map; \
367 static NameMapper mapper; \
Exception class for all of Sparta.
Visitor class for looking up type name.
The type-to-type name map. Not really necessary, but useful.
std::string getDesc() const
Get the Description.
std::string getKey() const
Get the key.
static TypeToTypeNameMap GBL_type_name_map
Map of internal typeid names to C++ names.
const std::string & getTypeName() const
Gets the compiler-independent readable type string of the value currently held.
static const std::string & lookupTypeName()
Determines if there is a known compiler-independent typename for type T.
static bool hasTypeNameFor()
Determines if there is a known compiler-independent typename for type T.
void setDesc(const std::string &desc)
Set the description.
KeyValue(const std::string &key, U val, const std::string &desc="")
Construct a Key/Value pair.
const T getValue() const
Get the value of this key/value.
void operator=(const T &rhp)
Assign a new value to this object.
T & getValueRef_()
Gets a reference to the value currently held by this object if the correct template type is specified...
Used to construct and throw a standard C++ exception. Inherits from std::exception.
Macros for handling exponential backoff.