mirror of https://github.com/vitalif/grive2
added type conversion to supported types
parent
658fb757e3
commit
540e3d82db
|
@ -20,6 +20,8 @@
|
|||
|
||||
#include "Val.hh"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace gr {
|
||||
|
||||
Val::Val( ) :
|
||||
|
@ -43,21 +45,25 @@ Val::TypeEnum Val::Type() const
|
|||
|
||||
const Val& Val::operator[]( const std::string& key ) const
|
||||
{
|
||||
static const Val null ;
|
||||
if ( Type() == object_type )
|
||||
{
|
||||
const Object& obj = As<Object>() ;
|
||||
Object::const_iterator i = obj.find(key) ;
|
||||
return i != obj.end() ? i->second : null ;
|
||||
}
|
||||
else
|
||||
return null ;
|
||||
const Object& obj = As<Object>() ;
|
||||
Object::const_iterator i = obj.find(key) ;
|
||||
if ( i != obj.end() )
|
||||
return i->second ;
|
||||
|
||||
// shut off compiler warning
|
||||
BOOST_THROW_EXCEPTION(Error() << NoKey_(key)) ;
|
||||
throw ;
|
||||
}
|
||||
|
||||
const Val& Val::operator[]( std::size_t index ) const
|
||||
{
|
||||
static const Val null ;
|
||||
return Type() == array_type ? As<Array>().at(index) : null ;
|
||||
const Array& ar = As<Array>() ;
|
||||
if ( index < ar.size() )
|
||||
return ar[index] ;
|
||||
|
||||
// shut off compiler warning
|
||||
BOOST_THROW_EXCEPTION(Error() << OutOfRange_(index)) ;
|
||||
throw ;
|
||||
}
|
||||
|
||||
void Val::Add( const std::string& key, const Val& value )
|
||||
|
@ -65,4 +71,22 @@ void Val::Add( const std::string& key, const Val& value )
|
|||
As<Object>().insert( std::make_pair(key, value) ) ;
|
||||
}
|
||||
|
||||
void Val::Swap( Val& val )
|
||||
{
|
||||
std::swap( m_base, val.m_base ) ;
|
||||
}
|
||||
|
||||
} // end of namespace
|
||||
|
||||
namespace std
|
||||
{
|
||||
void swap( gr::Val& v1, gr::Val& v2 )
|
||||
{
|
||||
v1.Swap( v2 ) ;
|
||||
}
|
||||
|
||||
ostream& operator<<( ostream& os, gr::Val::TypeEnum t )
|
||||
{
|
||||
return os << static_cast<int>(t) ;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,11 +20,14 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include "util/Exception.hh"
|
||||
|
||||
#include <cstddef>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <iosfwd>
|
||||
|
||||
namespace gr {
|
||||
|
||||
|
@ -33,10 +36,20 @@ class Val
|
|||
public :
|
||||
enum TypeEnum { null_type, bool_type, double_type, int_type, object_type, array_type, string_type } ;
|
||||
|
||||
struct Error : virtual Exception {} ;
|
||||
typedef boost::error_info<struct SrcType, TypeEnum> SrcType_ ;
|
||||
typedef boost::error_info<struct DestType, TypeEnum> DestType_ ;
|
||||
typedef boost::error_info<struct NoKey, std::string> NoKey_ ;
|
||||
typedef boost::error_info<struct OutOfRange,std::size_t> OutOfRange_ ;
|
||||
|
||||
private :
|
||||
template <typename T>
|
||||
struct Type2Enum ;
|
||||
|
||||
template <typename T>
|
||||
struct SupportType ;
|
||||
|
||||
public :
|
||||
typedef std::vector<Val> Array ;
|
||||
typedef std::map<std::string, Val> Object ;
|
||||
|
||||
|
@ -46,8 +59,28 @@ public :
|
|||
~Val() ;
|
||||
|
||||
template <typename T>
|
||||
Val( const T& t ) ;
|
||||
explicit Val( const T& t )
|
||||
{
|
||||
Assign(t) ;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Val& Assign( const T& t ) ;
|
||||
void Swap( Val& val ) ;
|
||||
|
||||
Val& operator=( const Val& val )
|
||||
{
|
||||
Val tmp(val) ;
|
||||
Swap(tmp) ;
|
||||
return *this ;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
Val& operator=( const T& t )
|
||||
{
|
||||
return Assign(t) ;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
const T& As() const ;
|
||||
|
||||
|
@ -85,47 +118,27 @@ private :
|
|||
static int EndArray( void *ctx ) ;
|
||||
} ;
|
||||
|
||||
template <>
|
||||
struct Val::Type2Enum<void>
|
||||
{
|
||||
static const TypeEnum type = null_type ;
|
||||
} ;
|
||||
template <> struct Val::Type2Enum<void> { static const TypeEnum type = null_type ; } ;
|
||||
template <> struct Val::Type2Enum<long long> { static const TypeEnum type = int_type ; } ;
|
||||
template <> struct Val::Type2Enum<bool> { static const TypeEnum type = bool_type ; } ;
|
||||
template <> struct Val::Type2Enum<double> { static const TypeEnum type = double_type ;} ;
|
||||
template <> struct Val::Type2Enum<std::string> { static const TypeEnum type = string_type ; } ;
|
||||
template <> struct Val::Type2Enum<Val::Array> { static const TypeEnum type = array_type ; } ;
|
||||
template <> struct Val::Type2Enum<Val::Object> { static const TypeEnum type = object_type ; } ;
|
||||
|
||||
template <>
|
||||
struct Val::Type2Enum<int>
|
||||
{
|
||||
static const TypeEnum type = int_type ;
|
||||
} ;
|
||||
template <> struct Val::SupportType<int> { typedef long long Type ; } ;
|
||||
template <> struct Val::SupportType<unsigned> { typedef long long Type ; } ;
|
||||
template <> struct Val::SupportType<long> { typedef long long Type ; } ;
|
||||
template <> struct Val::SupportType<unsigned long> { typedef long long Type ; } ;
|
||||
template <> struct Val::SupportType<short> { typedef long long Type ; } ;
|
||||
template <> struct Val::SupportType<unsigned short> { typedef long long Type ; } ;
|
||||
|
||||
template <>
|
||||
struct Val::Type2Enum<bool>
|
||||
{
|
||||
static const TypeEnum type = bool_type ;
|
||||
} ;
|
||||
|
||||
template <>
|
||||
struct Val::Type2Enum<double>
|
||||
{
|
||||
static const TypeEnum type = double_type ;
|
||||
} ;
|
||||
|
||||
template <>
|
||||
struct Val::Type2Enum<std::string>
|
||||
{
|
||||
static const TypeEnum type = string_type ;
|
||||
} ;
|
||||
|
||||
template <>
|
||||
struct Val::Type2Enum<Val::Array>
|
||||
{
|
||||
static const TypeEnum type = array_type ;
|
||||
} ;
|
||||
|
||||
template <>
|
||||
struct Val::Type2Enum<Val::Object>
|
||||
{
|
||||
static const TypeEnum type = object_type ;
|
||||
} ;
|
||||
template <> struct Val::SupportType<bool> { typedef bool Type ; } ;
|
||||
template <> struct Val::SupportType<double> { typedef double Type ; } ;
|
||||
template <> struct Val::SupportType<std::string> { typedef std::string Type ; } ;
|
||||
template <> struct Val::SupportType<const char*> { typedef std::string Type ; } ;
|
||||
template <> struct Val::SupportType<Val::Array> { typedef Val::Array Type ; } ;
|
||||
template <> struct Val::SupportType<Val::Object> { typedef Val::Object Type ; } ;
|
||||
|
||||
struct Val::Base
|
||||
{
|
||||
|
@ -135,7 +148,7 @@ struct Val::Base
|
|||
} ;
|
||||
|
||||
template <typename T>
|
||||
struct Val::Impl : public Base
|
||||
struct Val::Impl : public Base
|
||||
{
|
||||
T val ;
|
||||
Impl( const T& t ) : val(t) {}
|
||||
|
@ -151,23 +164,44 @@ struct Val::Impl<void> : public Base
|
|||
} ;
|
||||
|
||||
template <typename T>
|
||||
Val::Val( const T& t ) :
|
||||
m_base( new Impl<T>(t) )
|
||||
Val& Val::Assign( const T& t )
|
||||
{
|
||||
m_base.reset( new Impl<typename SupportType<T>::Type>(t) ) ;
|
||||
return *this ;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
const T& Val::As() const
|
||||
{
|
||||
const Impl<T> *impl = &dynamic_cast<const Impl<T>&>( *m_base ) ;
|
||||
return impl->val ;
|
||||
try
|
||||
{
|
||||
const Impl<T> *impl = &dynamic_cast<const Impl<T>&>( *m_base ) ;
|
||||
return impl->val ;
|
||||
}
|
||||
catch ( std::exception& e )
|
||||
{
|
||||
TypeEnum dest = Type2Enum<T>::type ;
|
||||
BOOST_THROW_EXCEPTION(
|
||||
Error() << SrcType_(Type()) << DestType_(dest)
|
||||
) ;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T& Val::As()
|
||||
{
|
||||
Impl<T> *impl = &dynamic_cast<Impl<T>&>( *m_base ) ;
|
||||
return impl->val ;
|
||||
try
|
||||
{
|
||||
Impl<T> *impl = &dynamic_cast<Impl<T>&>( *m_base ) ;
|
||||
return impl->val ;
|
||||
}
|
||||
catch ( std::exception& e )
|
||||
{
|
||||
TypeEnum dest = Type2Enum<T>::type ;
|
||||
BOOST_THROW_EXCEPTION(
|
||||
Error() << SrcType_(Type()) << DestType_(dest)
|
||||
) ;
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
|
@ -178,3 +212,8 @@ bool Val::Is() const
|
|||
|
||||
} // end of namespace
|
||||
|
||||
namespace std
|
||||
{
|
||||
void swap( gr::Val& v1, gr::Val& v2 ) ;
|
||||
ostream& operator<<( ostream& os, gr::Val::TypeEnum t ) ;
|
||||
}
|
||||
|
|
|
@ -38,14 +38,15 @@ BOOST_AUTO_TEST_CASE( TestSimpleTypes )
|
|||
BOOST_CHECK( null.Is<void>() ) ;
|
||||
|
||||
Val i( 100 ) ;
|
||||
BOOST_CHECK_EQUAL( i.As<int>(), 100 ) ;
|
||||
BOOST_CHECK_EQUAL( i.As<long long>(), 100 ) ;
|
||||
BOOST_CHECK_EQUAL( i.Type(), Val::int_type ) ;
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE( TestMap )
|
||||
{
|
||||
Val obj ;
|
||||
Val obj(( Val::Object() )) ;
|
||||
obj.Add( "key", Val( std::string("value") ) ) ;
|
||||
BOOST_CHECK_EQUAL( obj["key"].Type(), Val::string_type ) ;
|
||||
BOOST_CHECK_EQUAL( obj["key"].As<std::string>(), "value" ) ;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue