//| Copyright: (C) 2020-2024 Kevin Larke //| License: GNU GPL version 3.0 or above. See the accompanying LICENSE file. #ifndef cwObjectTemplate_H #define cwObjectTemplate_H namespace cw { objType_t* _objIdToType( objTypeId_t tid ); object_t* _objAllocate( objTypeId_t tid=kInvalidTId, object_t* parent=NULL ); object_t* _objCreateConainerNode( lex::handle_t lexH, object_t* parent, objTypeId_t tid ); object_t* _objAppendRightMostNode( object_t* parent, object_t* newNode ); template< typename T > object_t* _objSetLeafValue( object_t* obj, T value ) { cwLogError(kAssertFailRC,"Unhandled object type at leaf node."); return nullptr; } template<> object_t* _objSetLeafValue( object_t* obj, int8_t value ) { obj->u.i8 = value; obj->type = _objIdToType(kInt8TId); return obj; } template<> object_t* _objSetLeafValue( object_t* obj, uint8_t value ) { obj->u.u8 = value; obj->type = _objIdToType(kUInt8TId); return obj; } template<> object_t* _objSetLeafValue( object_t* obj, int16_t value ) { obj->u.i16 = value; obj->type = _objIdToType(kInt16TId); return obj; } template<> object_t* _objSetLeafValue( object_t* obj, uint16_t value ) { obj->u.u16 = value; obj->type = _objIdToType(kUInt16TId); return obj; } template<> object_t* _objSetLeafValue( object_t* obj, int32_t value ) { obj->u.i32 = value; obj->type = _objIdToType(kInt32TId); return obj; } template<> object_t* _objSetLeafValue( object_t* obj, uint32_t value ) { obj->u.u32 = value; obj->type = _objIdToType(kUInt32TId); return obj; } template<> object_t* _objSetLeafValue( object_t* obj, int64_t value ) { obj->u.i64 = value; obj->type = _objIdToType(kInt64TId); return obj; } template<> object_t* _objSetLeafValue( object_t* obj, uint64_t value ) { obj->u.u64 = value; obj->type = _objIdToType(kUInt64TId); return obj; } template<> object_t* _objSetLeafValue( object_t* obj, float value ) { obj->u.f = value; obj->type = _objIdToType(kFloatTId); return obj; } template<> object_t* _objSetLeafValue( object_t* obj, double value ) { obj->u.d = value; obj->type = _objIdToType(kDoubleTId); return obj; } template<> object_t* _objSetLeafValue( object_t* obj, bool value ) { obj->u.b = value; obj->type = _objIdToType(kBoolTId); return obj; } template<> object_t* _objSetLeafValue< char*>( object_t* obj, char* value ) { obj->u.str = value == nullptr ? nullptr : mem::duplStr(value); obj->type = _objIdToType(kStringTId); return obj; } template<> object_t* _objSetLeafValue( object_t* obj, const char* value ) { // cast 'const char*' to 'char*' return _objSetLeafValue(obj,(char*)value); } template< typename T > object_t* _objCallSetLeafValue( object_t* obj, const T& v ) { if( obj != nullptr ) { // The object value is about to be overwritten so be sure it is deallocated first. if( obj->type != nullptr ) obj->type->free_value(obj); // Set the object value and type id. obj = _objSetLeafValue(obj,v); } return obj; } template< typename T > object_t*_objCreateValueNode( object_t* obj, T value, const char* msg=nullptr, unsigned flags=0 ) { cwLogError(kObjAllocFailRC,"Unhandled type at value node."); return NULL; } template<> object_t* _objCreateValueNode( object_t* parent, uint8_t value, const char* msg, unsigned flags ) { return _objAppendRightMostNode( parent, _objCallSetLeafValue( _objAllocate(), value ) ); } template<> object_t* _objCreateValueNode( object_t* parent, int8_t value, const char* msg, unsigned flags ) { return _objAppendRightMostNode( parent, _objCallSetLeafValue( _objAllocate(), value ) ); } template<> object_t* _objCreateValueNode( object_t* parent, uint16_t value, const char* msg, unsigned flags ) { return _objAppendRightMostNode( parent, _objCallSetLeafValue( _objAllocate(), value ) ); } template<> object_t* _objCreateValueNode( object_t* parent, int16_t value, const char* msg, unsigned flags ) { return _objAppendRightMostNode( parent, _objCallSetLeafValue( _objAllocate(), value ) ); } template<> object_t* _objCreateValueNode( object_t* parent, uint32_t value, const char* msg, unsigned flags ) { return _objAppendRightMostNode( parent, _objCallSetLeafValue( _objAllocate(), value ) ); } template<> object_t* _objCreateValueNode( object_t* parent, int32_t value, const char* msg, unsigned flags ) { return _objAppendRightMostNode( parent, _objCallSetLeafValue( _objAllocate(), value ) ); } template<> object_t* _objCreateValueNode( object_t* parent, uint64_t value, const char* msg, unsigned flags ) { return _objAppendRightMostNode( parent, _objCallSetLeafValue( _objAllocate(), value ) ); } template<> object_t* _objCreateValueNode( object_t* parent, int64_t value, const char* msg, unsigned flags ) { return _objAppendRightMostNode( parent, _objCallSetLeafValue( _objAllocate(), value ) ); } template<> object_t* _objCreateValueNode( object_t* parent, float value, const char* msg, unsigned flags ) { return _objAppendRightMostNode( parent, _objCallSetLeafValue( _objAllocate(), value ) ); } template<> object_t* _objCreateValueNode( object_t* parent, double value, const char* msg, unsigned flags ) { return _objAppendRightMostNode( parent, _objCallSetLeafValue( _objAllocate(), value ) ); } template<> object_t* _objCreateValueNode< char*>( object_t* parent, char* value, const char* msg, unsigned flags ) { return _objAppendRightMostNode( parent, _objCallSetLeafValue( _objAllocate(), value ) ); } template<> object_t* _objCreateValueNode( object_t* parent, const char* value, const char* msg, unsigned flags ) { return _objAppendRightMostNode( parent, _objCallSetLeafValue( _objAllocate(), value ) ); } template<> object_t* _objCreateValueNode( object_t* parent, bool value, const char* msg, unsigned flags ) { return _objAppendRightMostNode( parent, _objCallSetLeafValue( _objAllocate(), value ) ); } template< typename T > object_t*_objCreatePairNode( object_t* parentObj, const char* label, const T& value, const char* msg=nullptr, unsigned flags=0 ) { object_t* pair = _objAppendRightMostNode(parentObj, _objAllocate( kPairTId, parentObj) ); _objCreateValueNode( pair, label, msg, flags ); return _objCreateValueNode( pair, value, msg, flags ); } template< typename T > rc_t getObjectValue( const T& src, unsigned tid, void* dst, const char* typeLabel ) { rc_t rc = kOkRC; switch( tid ) { case kCharTId: rc = numeric_convert( src, *static_cast(dst) ); break; case kInt8TId: rc = numeric_convert( src, *static_cast(dst) ); break; case kUInt8TId: rc = numeric_convert( src, *static_cast(dst) );break; case kInt16TId: rc = numeric_convert( src, *static_cast(dst) );break; case kUInt16TId: rc = numeric_convert( src, *static_cast(dst) );break; case kInt32TId: rc = numeric_convert( src, *static_cast(dst) );break; case kUInt32TId: rc = numeric_convert( src, *static_cast(dst) );break; case kInt64TId: rc = numeric_convert( src, *static_cast(dst) );break; case kUInt64TId: rc = numeric_convert( src, *static_cast(dst) );break; case kFloatTId: rc = numeric_convert( src, *static_cast(dst) );break; case kDoubleTId: rc = numeric_convert( src, *static_cast(dst) );break; case kBoolTId: rc = numeric_convert( src, *static_cast(dst) );break; default: cwAssert(0); rc = cwLogError(kInvalidArgRC,"Invalid destination type id: %i in conversion from '%s'.", tid, typeLabel ); } return rc; } } #endif