#include #include #include #include using namespace std ; #include #include #include #include #include namespace mpl = boost::mpl; struct NoneType : public mpl::na { }; struct boost::recursive_variant_{}; class fioVariant; namespace { typedef mpl::vector < NoneType , int , double , string , boost::recursive_wrapper < vector > , boost::recursive_wrapper < map > , bool > VariantTypes; typedef boost::make_recursive_variant_over < VariantTypes > :: type fioVariant_; } typedef vector VariantVec; typedef VariantVec::iterator VariantVecIter; typedef VariantVec::const_iterator VariantVecIterC; typedef map VariantMap; typedef VariantMap::iterator VariantMapIter; typedef VariantMap::const_iterator VariantMapIterC; class fioVariant { #define TYPE_CHECKER(name, type) \ struct name : public boost::static_visitor \ { \ template bool operator() (const T&) const { return false ; } \ template <> bool operator() (const type&) const { return true ; } \ }; \ \ template<> \ struct typeCheckerTag { typedef name tag ; } private: template struct typeCheckerTag { }; TYPE_CHECKER(none_type_checker, NoneType); TYPE_CHECKER(int_type_checker, int); TYPE_CHECKER(vec_type_checker, VariantVec); TYPE_CHECKER(map_type_checker, VariantMap); TYPE_CHECKER(string_type_checker, std::string); TYPE_CHECKER(double_type_checker, double); TYPE_CHECKER(bool_type_checker, bool); template struct invalid_type { static bool check_type_of(const fioVariant_& p_var) { return false ; } }; template struct valid_type { static bool check_type_of(const fioVariant_& p_var) { typedef typename typeCheckerTag::tag tag; return boost::apply_visitor(tag(), p_var); } }; template struct variant_type : public mpl::if_ < typename mpl::contains::type , valid_type , invalid_type >::type {}; public: explicit fioVariant () : m_var (NoneType()) { } explicit fioVariant (int p_i) : m_var(p_i) { } explicit fioVariant (const string& p_s) : m_var(p_s) { } explicit fioVariant (const char* p_s) : m_var(string(p_s)) { } explicit fioVariant (bool p_b) : m_var(p_b) { } explicit fioVariant (const VariantMap& p_vm) : m_var(p_vm) { } template bool isType() { return variant_type::check_type_of(m_var); } bool empty() { return isType(); } private: fioVariant_ m_var; }; int main (void) { VariantMap vm; vm.insert (make_pair ("Some String", 10)); vm.insert (make_pair ("Some Other String", 5)); fioVariant fio (vm); if (fio.isType()) cout << "Map Type" << endl ; else cout << "Not a Map type" << endl; if (fio.empty()) cout << "Empty Type" << endl ; }