Skip to content

Instantly share code, notes, and snippets.

@tyhenry
Created December 18, 2019 16:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tyhenry/19c88fd0edd9b2f0b30fbd7ee13fc79c to your computer and use it in GitHub Desktop.
Save tyhenry/19c88fd0edd9b2f0b30fbd7ee13fc79c to your computer and use it in GitHub Desktop.
C++ "dictionary" - mixed-type map
// C++11 "any" class for multi-type storage
// https://stackoverflow.com/a/24702400/5195277
// (better to use C++17 std::any or std::variant)
class AnyBase
{
public:
virtual ~AnyBase() = 0;
};
inline AnyBase::~AnyBase() {}
template<class T>
class Any : public AnyBase
{
public:
typedef T Type;
explicit Any(const Type& data) : data(data) {}
Any() {}
Type data;
};
template <class T>
using AnyMap = std::map<T, std::unique_ptr<AnyBase>>;
using AnyDict = AnyMap<std::string>;
// usage:
/*
AnyDict anydict;
anydict["number"].reset(new Any<int>(5)); // create / update
anydict["text"].reset(new Any<std::string>("5"));
// throws std::bad_cast if not really Any<int>
int value = dynamic_cast<Any<int>&>(*anydict["number"]).data;
*/
#include "Any.h"
class Dictionary
{
public:
bool has( const std::string& key )
{
return std::find( dict.begin(), dict.end(), key ) != dict.end();
}
template <class T>
bool find( const std::string& key, T& result ) const
{
if (!has(key)){ return false; }
try {
// throws std::bad_cast if wrong type
result = dynamic_cast<Any<T>&>( *dict.at(key) ).data;
return true;
} catch ( std::bad_cast& e ) {
std::cerr << "Dictionary ['" << key << "'] found, but wrong type - exception: " << e.what() << std::endl;
// todo: typeid
} // todo: catch others
return false;
}
template <class T>
void set( const std::string& key, const T& value )
{
dict[key].reset( new Any<T>( value ) ); // create / update
}
template <class T>
bool create( const std::string& key, const T& value )
{
if ( !has( key ) ) { // not found?
set( key, value );
return true;
}
return false;
}
protected:
AnyDict dict;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment