Original Post
First off, some code from my experimental entity database system:- ValueData And then the generic Value structures:- I have created override 'helper' classes to allow easy use of typed data:- Example String: ValueDataType is an int that allows the system to store a 'type' associated with the data (note that VT_STRING is just an int). The idea is that users can register their own types with the system and provided they adhere to the interface, the system can query attributes of them transparently. I want to be able to compare the values of two types. For this purpose I have created an interface and implemented it using templates:- To test for equality between two types:
struct IValueData
{
virtual ValueDataType get_type() const = 0;
virtual ~IValueData() { }
};
template < typename T >
class ValueData : public IValueData
{
public:
explicit ValueData( T a_data, ValueDataType a_type );
virtual const T get_data() { return m_value; }
virtual void set_data( const T a_data ) { m_value = a_data; }
ValueDataType get_type() const { return m_type; }
};
typedef boost::shared_ptr<IValueData> IValueDataPtr;
class Value
{
public:
explicit Value();
explicit Value( IValueDataPtr a_data );
// explicit Value( const Value &a_src );
virtual ~Value() { }
IValueDataPtr get_data();
void set_data( IValueDataPtr a_data );
ValueDataType get_datatype() const;
};
class ValueData_String : public ValueData<std::string>
{
public:
ValueData_String( const std::string &a_value ) : ValueData<std::string>( a_value, VT_STRING ) { }
virtual ~ValueData_String() { }
};
class ITest
{
public:
virtual bool_t test( IValueDataPtr a_lhs, IValueDataPtr a_rhs ) = 0;
};
typedef boost::shared_ptr<ITest> ITestPtr;
template < class T1, class T2 >
class EqualityTest : public ITest//< T1, T2 >
{
public:
bool_t test( IValueDataPtr a_lhs, IValueDataPtr a_rhs )
{
T1 *v_left = (T1*)a_lhs.get();
T2 *v_right = (T2*)a_rhs.get();
if ( v_left->get_data() == v_right->get_data() )
{
return 1;
}
return 0;
}
};
ITestPtr value_test = ITestPtr( new EqualityTest<ValueData_String, ValueData_String>() );
if (value_test->test( blah, blah2 ) )
{
// etc
}
This all works perfectly... except for one thing, I need to be able to map the VT_STRING int 'types' to real C++ types. In an ideal world, I'd want some form of lookup to say that VT_STRING maps to ValueData_String (likewise, VT_INT to ValueData_Integer, VT_NULL to ValueData_Null, etc). The problem is that I want to be able to allow for comparisons for VT_FLOAT to VT_INT, or VT_YOURUSERTYPE to VT_STRING - the current system allows this through the use of templates (provided the comparing types have appropriate equality operators). In pseduosyntax:-
ITest test = new EqualityTest( CPPTypeLookup::GetCPPType( VT_STRING ), CPPTypeLookup::GetCPPType( VT_YOURTYPE ) );
Could I employ this using the visitor pattern somehow? Any ideas?