1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
|
#include <iostream>
#include <map>
#include <any>
#include <string>
#include <vector>
#include <typeinfo>
using name_value_map = std::map< std::string, std::any > ;
template < typename T > T* get_ptr( name_value_map& map, const std::string& name )
{
const auto iter = map.find(name) ;
if( iter != map.end() )
return std::any_cast<T>( std::addressof(iter->second) ) ;
else return nullptr ;
}
template < typename T > const T* get_ptr( const name_value_map& map, const std::string& name )
{
const auto iter = map.find(name) ;
if( iter != map.end() )
return std::any_cast<T>( std::addressof(iter->second) ) ;
else return nullptr ;
}
template < typename T > T& get( name_value_map& map, const std::string& name )
{
auto ptr = get_ptr<T>( map, name ) ;
if( ptr == nullptr ) throw std::domain_error( "not found / wrong type" ) ;
return *ptr ;
}
template < typename T > const T& get( const name_value_map& map, const std::string& name )
{
auto ptr = get_ptr<T>( map, name ) ;
if( ptr == nullptr ) throw std::domain_error( "not found / wrong type" ) ;
return *ptr ;
}
int main()
{
name_value_map map ;
map["name_one"] = std::string( "hello" ) ;
std::cout << get<std::string>( map, "name_one" ) << '\n' ;
map["name_two"] = 5 ;
get<int>( map, "name_two" ) *= 100 ;
map["sequence"] = std::vector<int> { 0, 1, 2, 3, 4, 5 } ;
get< std::vector<int> >( map, "sequence" ).push_back(6) ;
for( int v : get< std::vector<int> >( map, "sequence" ) ) std::cout << v << ' ' ;
std::cout << '\n' ;
std::cout << "------------------------------------ - \n" ;
for( const auto& pair : map )
std::cout << "key: " << pair.first << " => " << pair.second.type().name() << '\n' ;
std::cout << "------------------------------------ - \n" ;
map["name_one"] = 1234567890123456LL ;
std::cout << get<long long>( map, "name_one" ) << '\n' ;
try { std::cout << get<std::string>( map, "name_one" ) << '\n' ; }
catch( const std::exception& ) { std::cout << "*** error: get<std::string> failed\n" ; }
double* ptr = get_ptr<double>( map, "bad name" ) ;
if(ptr) std::cout << *ptr << '\n' ;
else std::cout << "*** error: get_ptr<double> failed\n" ;
}
|