genesis                 1 #ifndef JSON_SPIRIT_VALUE
genesis                 2 #define JSON_SPIRIT_VALUE
genesis                 3 
genesis                 4 
genesis                 5 
genesis                 6 
genesis                 7 
genesis                 8 
genesis                 9 #if defined(_MSC_VER) && (_MSC_VER >= 1020)
genesis                10 # pragma once
genesis                11 #endif
genesis                12 
genesis                13 #include <vector>
genesis                14 #include <map>
genesis                15 #include <string>
genesis                16 #include <cassert>
genesis                17 #include <sstream>
genesis                18 #include <stdexcept>
genesis                19 #include <boost/config.hpp> 
genesis                20 #include <boost/cstdint.hpp> 
genesis                21 #include <boost/shared_ptr.hpp> 
genesis                22 #include <boost/variant.hpp> 
genesis                23 
genesis                24 namespace json_spirit
genesis                25 {
genesis                26     enum Value_type{ obj_type, array_type, str_type, bool_type, int_type, real_type, null_type };
genesis                27     static const char* Value_type_name[]={"obj", "array", "str", "bool", "int", "real", "null"};
genesis                28 
genesis                29     template< class Config >    
genesis                30                                 
genesis                31     class Value_impl
genesis                32     {
genesis                33     public:
genesis                34 
genesis                35         typedef Config Config_type;
genesis                36         typedef typename Config::String_type String_type;
genesis                37         typedef typename Config::Object_type Object;
genesis                38         typedef typename Config::Array_type Array;
genesis                39         typedef typename String_type::const_pointer Const_str_ptr;  
genesis                40 
genesis                41         Value_impl();  
genesis                42         Value_impl( Const_str_ptr      value ); 
genesis                43         Value_impl( const String_type& value );
genesis                44         Value_impl( const Object&      value );
genesis                45         Value_impl( const Array&       value );
genesis                46         Value_impl( bool               value );
genesis                47         Value_impl( int                value );
genesis                48         Value_impl( boost::int64_t     value );
genesis                49         Value_impl( boost::uint64_t    value );
genesis                50         Value_impl( double             value );
genesis                51 
genesis                52         Value_impl( const Value_impl& other );
genesis                53 
genesis                54         bool operator==( const Value_impl& lhs ) const;
genesis                55 
genesis                56         Value_impl& operator=( const Value_impl& lhs );
genesis                57 
genesis                58         Value_type type() const;
genesis                59 
genesis                60         bool is_uint64() const;
genesis                61         bool is_null() const;
genesis                62 
genesis                63         const String_type& get_str()    const;
genesis                64         const Object&      get_obj()    const;
genesis                65         const Array&       get_array()  const;
genesis                66         bool               get_bool()   const;
genesis                67         int                get_int()    const;
genesis                68         boost::int64_t     get_int64()  const;
genesis                69         boost::uint64_t    get_uint64() const;
genesis                70         double             get_real()   const;
genesis                71 
genesis                72         Object& get_obj();
genesis                73         Array&  get_array();
genesis                74 
genesis                75         template< typename T > T get_value() const;  
genesis                76                                                      
genesis                77 
genesis                78         static const Value_impl null;
genesis                79 
genesis                80     private:
genesis                81 
genesis                82         void check_type( const Value_type vtype ) const;
genesis                83 
genesis                84         typedef boost::variant< String_type, 
genesis                85                                 boost::recursive_wrapper< Object >, boost::recursive_wrapper< Array >, 
genesis                86                                 bool, boost::int64_t, double > Variant;
genesis                87 
genesis                88         Value_type type_;
genesis                89         Variant v_;
genesis                90         bool is_uint64_;
genesis                91     };
genesis                92 
genesis                93     
genesis                94 
genesis                95     template< class Config >
genesis                96     struct Pair_impl
genesis                97     {
genesis                98         typedef typename Config::String_type String_type;
genesis                99         typedef typename Config::Value_type Value_type;
genesis               100 
genesis               101         Pair_impl( const String_type& name, const Value_type& value );
genesis               102 
genesis               103         bool operator==( const Pair_impl& lhs ) const;
genesis               104 
genesis               105         String_type name_;
genesis               106         Value_type value_;
genesis               107     };
genesis               108 
genesis               109     template< class String >
genesis               110     struct Config_vector
genesis               111     {
genesis               112         typedef String String_type;
genesis               113         typedef Value_impl< Config_vector > Value_type;
genesis               114         typedef Pair_impl < Config_vector > Pair_type;
genesis               115         typedef std::vector< Value_type > Array_type;
genesis               116         typedef std::vector< Pair_type > Object_type;
genesis               117 
genesis               118         static Value_type& add( Object_type& obj, const String_type& name, const Value_type& value )
genesis               119         {
genesis               120             obj.push_back( Pair_type( name , value ) );
genesis               121 
genesis               122             return obj.back().value_;
genesis               123         }
genesis               124                 
genesis               125         static String_type get_name( const Pair_type& pair )
genesis               126         {
genesis               127             return pair.name_;
genesis               128         }
genesis               129                 
genesis               130         static Value_type get_value( const Pair_type& pair )
genesis               131         {
genesis               132             return pair.value_;
genesis               133         }
genesis               134     };
genesis               135 
genesis               136     
genesis               137 
genesis               138     typedef Config_vector< std::string > Config;
genesis               139 
genesis               140     typedef Config::Value_type  Value;
genesis               141     typedef Config::Pair_type   Pair;
genesis               142     typedef Config::Object_type Object;
genesis               143     typedef Config::Array_type  Array;
genesis               144 
genesis               145     
genesis               146 
genesis               147 #ifndef BOOST_NO_STD_WSTRING
genesis               148 
genesis               149     typedef Config_vector< std::wstring > wConfig;
genesis               150 
genesis               151     typedef wConfig::Value_type  wValue;
genesis               152     typedef wConfig::Pair_type   wPair;
genesis               153     typedef wConfig::Object_type wObject;
genesis               154     typedef wConfig::Array_type  wArray;
genesis               155 #endif
genesis               156 
genesis               157     
genesis               158 
genesis               159     template< class String >
genesis               160     struct Config_map
genesis               161     {
genesis               162         typedef String String_type;
genesis               163         typedef Value_impl< Config_map > Value_type;
genesis               164         typedef std::vector< Value_type > Array_type;
genesis               165         typedef std::map< String_type, Value_type > Object_type;
genesis               166         typedef typename Object_type::value_type Pair_type;
genesis               167 
genesis               168         static Value_type& add( Object_type& obj, const String_type& name, const Value_type& value )
genesis               169         {
genesis               170             return obj[ name ] = value;
genesis               171         }
genesis               172                 
genesis               173         static String_type get_name( const Pair_type& pair )
genesis               174         {
genesis               175             return pair.first;
genesis               176         }
genesis               177                 
genesis               178         static Value_type get_value( const Pair_type& pair )
genesis               179         {
genesis               180             return pair.second;
genesis               181         }
genesis               182     };
genesis               183 
genesis               184     
genesis               185 
genesis               186     typedef Config_map< std::string > mConfig;
genesis               187 
genesis               188     typedef mConfig::Value_type  mValue;
genesis               189     typedef mConfig::Object_type mObject;
genesis               190     typedef mConfig::Array_type  mArray;
genesis               191 
genesis               192     
genesis               193 
genesis               194 #ifndef BOOST_NO_STD_WSTRING
genesis               195 
genesis               196     typedef Config_map< std::wstring > wmConfig;
genesis               197 
genesis               198     typedef wmConfig::Value_type  wmValue;
genesis               199     typedef wmConfig::Object_type wmObject;
genesis               200     typedef wmConfig::Array_type  wmArray;
genesis               201 
genesis               202 #endif
genesis               203 
genesis               204     
genesis               205     
genesis               206     
genesis               207 
genesis               208     template< class Config >
genesis               209     const Value_impl< Config > Value_impl< Config >::null;
genesis               210 
genesis               211     template< class Config >
genesis               212     Value_impl< Config >::Value_impl()
genesis               213     :   type_( null_type )
genesis               214     ,   is_uint64_( false )
genesis               215     {
genesis               216     }
genesis               217 
genesis               218     template< class Config >
genesis               219     Value_impl< Config >::Value_impl( const Const_str_ptr value )
genesis               220     :   type_( str_type )
genesis               221     ,   v_( String_type( value ) )
genesis               222     ,   is_uint64_( false )
genesis               223     {
genesis               224     }
genesis               225 
genesis               226     template< class Config >
genesis               227     Value_impl< Config >::Value_impl( const String_type& value )
genesis               228     :   type_( str_type )
genesis               229     ,   v_( value )
genesis               230     ,   is_uint64_( false )
genesis               231     {
genesis               232     }
genesis               233 
genesis               234     template< class Config >
genesis               235     Value_impl< Config >::Value_impl( const Object& value )
genesis               236     :   type_( obj_type )
genesis               237     ,   v_( value )
genesis               238     ,   is_uint64_( false )
genesis               239     {
genesis               240     }
genesis               241 
genesis               242     template< class Config >
genesis               243     Value_impl< Config >::Value_impl( const Array& value )
genesis               244     :   type_( array_type )
genesis               245     ,   v_( value )
genesis               246     ,   is_uint64_( false )
genesis               247     {
genesis               248     }
genesis               249 
genesis               250     template< class Config >
genesis               251     Value_impl< Config >::Value_impl( bool value )
genesis               252     :   type_( bool_type )
genesis               253     ,   v_( value )
genesis               254     ,   is_uint64_( false )
genesis               255     {
genesis               256     }
genesis               257 
genesis               258     template< class Config >
genesis               259     Value_impl< Config >::Value_impl( int value )
genesis               260     :   type_( int_type )
genesis               261     ,   v_( static_cast< boost::int64_t >( value ) )
genesis               262     ,   is_uint64_( false )
genesis               263     {
genesis               264     }
genesis               265 
genesis               266     template< class Config >
genesis               267     Value_impl< Config >::Value_impl( boost::int64_t value )
genesis               268     :   type_( int_type )
genesis               269     ,   v_( value )
genesis               270     ,   is_uint64_( false )
genesis               271     {
genesis               272     }
genesis               273 
genesis               274     template< class Config >
genesis               275     Value_impl< Config >::Value_impl( boost::uint64_t value )
genesis               276     :   type_( int_type )
genesis               277     ,   v_( static_cast< boost::int64_t >( value ) )
genesis               278     ,   is_uint64_( true )
genesis               279     {
genesis               280     }
genesis               281 
genesis               282     template< class Config >
genesis               283     Value_impl< Config >::Value_impl( double value )
genesis               284     :   type_( real_type )
genesis               285     ,   v_( value )
genesis               286     ,   is_uint64_( false )
genesis               287     {
genesis               288     }
genesis               289 
genesis               290     template< class Config >
genesis               291     Value_impl< Config >::Value_impl( const Value_impl< Config >& other )
genesis               292     :   type_( other.type() )
genesis               293     ,   v_( other.v_ )
genesis               294     ,   is_uint64_( other.is_uint64_ )
genesis               295     {
genesis               296     }
genesis               297 
genesis               298     template< class Config >
genesis               299     Value_impl< Config >& Value_impl< Config >::operator=( const Value_impl& lhs )
genesis               300     {
genesis               301         Value_impl tmp( lhs );
genesis               302 
genesis               303         std::swap( type_, tmp.type_ );
genesis               304         std::swap( v_, tmp.v_ );
genesis               305         std::swap( is_uint64_, tmp.is_uint64_ );
genesis               306 
genesis               307         return *this;
genesis               308     }
genesis               309 
genesis               310     template< class Config >
genesis               311     bool Value_impl< Config >::operator==( const Value_impl& lhs ) const
genesis               312     {
genesis               313         if( this == &lhs ) return true;
genesis               314 
genesis               315         if( type() != lhs.type() ) return false;
genesis               316 
genesis               317         return v_ == lhs.v_; 
genesis               318     }
genesis               319 
genesis               320     template< class Config >
genesis               321     Value_type Value_impl< Config >::type() const
genesis               322     {
genesis               323         return type_;
genesis               324     }
genesis               325 
genesis               326     template< class Config >
genesis               327     bool Value_impl< Config >::is_uint64() const
genesis               328     {
genesis               329         return is_uint64_;
genesis               330     }
genesis               331 
genesis               332     template< class Config >
genesis               333     bool Value_impl< Config >::is_null() const
genesis               334     {
genesis               335         return type() == null_type;
genesis               336     }
genesis               337 
genesis               338     template< class Config >
genesis               339     void Value_impl< Config >::check_type( const Value_type vtype ) const
genesis               340     {
genesis               341         if( type() != vtype ) 
genesis               342         {
genesis               343             std::ostringstream os;
genesis               344 
genesis               345             
genesis               346             os << "value is type " << Value_type_name[type()] << ", expected " << Value_type_name[vtype];
genesis               347 
genesis               348             throw std::runtime_error( os.str() );
genesis               349         }
genesis               350     }
genesis               351 
genesis               352     template< class Config >
genesis               353     const typename Config::String_type& Value_impl< Config >::get_str() const
genesis               354     {
genesis               355         check_type(  str_type );
genesis               356 
genesis               357         return *boost::get< String_type >( &v_ );
genesis               358     }
genesis               359 
genesis               360     template< class Config >
genesis               361     const typename Value_impl< Config >::Object& Value_impl< Config >::get_obj() const
genesis               362     {
genesis               363         check_type( obj_type );
genesis               364 
genesis               365         return *boost::get< Object >( &v_ );
genesis               366     }
genesis               367      
genesis               368     template< class Config >
genesis               369     const typename Value_impl< Config >::Array& Value_impl< Config >::get_array() const
genesis               370     {
genesis               371         check_type(  array_type );
genesis               372 
genesis               373         return *boost::get< Array >( &v_ );
genesis               374     }
genesis               375      
genesis               376     template< class Config >
genesis               377     bool Value_impl< Config >::get_bool() const
genesis               378     {
genesis               379         check_type(  bool_type );
genesis               380 
genesis               381         return boost::get< bool >( v_ );
genesis               382     }
genesis               383      
genesis               384     template< class Config >
genesis               385     int Value_impl< Config >::get_int() const
genesis               386     {
genesis               387         check_type(  int_type );
genesis               388 
genesis               389         return static_cast< int >( get_int64() );
genesis               390     }
genesis               391     
genesis               392     template< class Config >
genesis               393     boost::int64_t Value_impl< Config >::get_int64() const
genesis               394     {
genesis               395         check_type(  int_type );
genesis               396 
genesis               397         return boost::get< boost::int64_t >( v_ );
genesis               398     }
genesis               399     
genesis               400     template< class Config >
genesis               401     boost::uint64_t Value_impl< Config >::get_uint64() const
genesis               402     {
genesis               403         check_type(  int_type );
genesis               404 
genesis               405         return static_cast< boost::uint64_t >( get_int64() );
genesis               406     }
genesis               407 
genesis               408     template< class Config >
genesis               409     double Value_impl< Config >::get_real() const
genesis               410     {
genesis               411         if( type() == int_type )
genesis               412         {
genesis               413             return is_uint64() ? static_cast< double >( get_uint64() )
genesis               414                                : static_cast< double >( get_int64() );
genesis               415         }
genesis               416 
genesis               417         check_type(  real_type );
genesis               418 
genesis               419         return boost::get< double >( v_ );
genesis               420     }
genesis               421 
genesis               422     template< class Config >
genesis               423     typename Value_impl< Config >::Object& Value_impl< Config >::get_obj()
genesis               424     {
genesis               425         check_type(  obj_type );
genesis               426 
genesis               427         return *boost::get< Object >( &v_ );
genesis               428     }
genesis               429 
genesis               430     template< class Config >
genesis               431     typename Value_impl< Config >::Array& Value_impl< Config >::get_array()
genesis               432     {
genesis               433         check_type(  array_type );
genesis               434 
genesis               435         return *boost::get< Array >( &v_ );
genesis               436     }
genesis               437 
genesis               438     template< class Config >
genesis               439     Pair_impl< Config >::Pair_impl( const String_type& name, const Value_type& value )
genesis               440     :   name_( name )
genesis               441     ,   value_( value )
genesis               442     {
genesis               443     }
genesis               444 
genesis               445     template< class Config >
genesis               446     bool Pair_impl< Config >::operator==( const Pair_impl< Config >& lhs ) const
genesis               447     {
genesis               448         if( this == &lhs ) return true;
genesis               449 
genesis               450         return ( name_ == lhs.name_ ) && ( value_ == lhs.value_ );
genesis               451     }
genesis               452 
genesis               453     
genesis               454     
genesis               455     template < class String_type >
genesis               456     String_type to_str( const char* c_str )
genesis               457     {
genesis               458         String_type result;
genesis               459 
genesis               460         for( const char* p = c_str; *p != 0; ++p )
genesis               461         {
genesis               462             result += *p;
genesis               463         }
genesis               464 
genesis               465         return result;
genesis               466     }
genesis               467 
genesis               468     
genesis               469 
genesis               470     namespace internal_
genesis               471     {
genesis               472         template< typename T >
genesis               473         struct Type_to_type
genesis               474         {
genesis               475         };
genesis               476 
genesis               477         template< class Value > 
genesis               478         int get_value( const Value& value, Type_to_type< int > )
genesis               479         {
genesis               480             return value.get_int();
genesis               481         }
genesis               482        
genesis               483         template< class Value > 
genesis               484         boost::int64_t get_value( const Value& value, Type_to_type< boost::int64_t > )
genesis               485         {
genesis               486             return value.get_int64();
genesis               487         }
genesis               488        
genesis               489         template< class Value > 
genesis               490         boost::uint64_t get_value( const Value& value, Type_to_type< boost::uint64_t > )
genesis               491         {
genesis               492             return value.get_uint64();
genesis               493         }
genesis               494        
genesis               495         template< class Value > 
genesis               496         double get_value( const Value& value, Type_to_type< double > )
genesis               497         {
genesis               498             return value.get_real();
genesis               499         }
genesis               500        
genesis               501         template< class Value > 
genesis               502         typename Value::String_type get_value( const Value& value, Type_to_type< typename Value::String_type > )
genesis               503         {
genesis               504             return value.get_str();
genesis               505         }
genesis               506        
genesis               507         template< class Value > 
genesis               508         typename Value::Array get_value( const Value& value, Type_to_type< typename Value::Array > )
genesis               509         {
genesis               510             return value.get_array();
genesis               511         }
genesis               512        
genesis               513         template< class Value > 
genesis               514         typename Value::Object get_value( const Value& value, Type_to_type< typename Value::Object > )
genesis               515         {
genesis               516             return value.get_obj();
genesis               517         }
genesis               518        
genesis               519         template< class Value > 
genesis               520         bool get_value( const Value& value, Type_to_type< bool > )
genesis               521         {
genesis               522             return value.get_bool();
genesis               523         }
genesis               524     }
genesis               525 
genesis               526     template< class Config >
genesis               527     template< typename T > 
genesis               528     T Value_impl< Config >::get_value() const
genesis               529     {
genesis               530         return internal_::get_value( *this, internal_::Type_to_type< T >() );
genesis               531     }
genesis               532 }
genesis               533 
genesis               534 #endif