Changeset 111:ed1aeb74c1b6 in rrlib_rtti


Ignore:
Timestamp:
30.09.2018 15:50:31 (2 months ago)
Author:
Max Reichardt <mreichardt@…>
Branch:
17.03
Parents:
109:a996bf55aec4 (diff), 110:a4e73e3bd84b (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Phase:
public
Tags:
tip
Message:

Merge with 14.08

File:
1 edited

Legend:

Unmodified
Added
Removed
  • tGenericObject.h

    r110 r111  
    4646// External includes (system with <>, local with "") 
    4747//---------------------------------------------------------------------- 
    48 #include "rrlib/serialization/serialization.h" 
    4948 
    5049//---------------------------------------------------------------------- 
    5150// Internal includes with "" 
    5251//---------------------------------------------------------------------- 
    53 #include "rrlib/rtti/tTypedObject.h" 
     52#include "rrlib/rtti/tTypedPointer.h" 
    5453 
    5554//---------------------------------------------------------------------- 
     
    7574 * Provides base functionality such as deep copying, type information 
    7675 * and serialization for wrapped object. 
    77  * It also asserts that casting back is only possible to the original type. 
     76 * It also asserts that casting back is only possible to the original/underlying type. 
    7877 * 
    7978 * This allows to handle objects in a uniform way. 
     79 * 
     80 * Unlike tTypedPointer, tGenericObject is also concerned with 
     81 * creation, destruction, and ownership of the object it points to. 
     82 * The wrapped pointer is never nullptr. 
     83 * 
     84 * Generic objects are constructed with the tType class. 
    8085 */ 
    81 class tGenericObject : public tTypedObject, private util::tNoncopyable 
     86class tGenericObject : private util::tNoncopyable 
    8287{ 
    8388 
     
    8792public: 
    8893 
    89   // to ensure that all generic objects have virtual destructor 
    90   virtual ~tGenericObject() {} 
    91  
    92   /*! 
    93    * Clear any shared resources that this object holds on to 
    94    * (e.g. for reusing object in pool) 
    95    */ 
    96   virtual void Clear() = 0; 
    97  
    98   /*! 
    99    * Deep copy source object to this object 
    100    * (types MUST match) 
    101    * 
    102    * \param source Source object 
    103    */ 
    104   inline void DeepCopyFrom(const tGenericObject& source, tFactory* f = NULL) 
    105   { 
    106     assert((source.type == this->type) && "Types must match"); 
    107     DeepCopyFrom(source.wrapped, f); 
    108   } 
    109  
    110   /*! 
    111    * Does object equal other object? 
    112    * If rrlib_serialization is not present, this only works for types 
    113    * that have the == operator implemented (or the two objects share the same address) 
    114    * 
    115    * (not very efficient/RT-capable - should therefore not be called regular loops) 
    116    * 
    117    * \return True, if... 
    118    *  1) both objects have the same address 
    119    *  2) the == operator returns true for both objects 
    120    *  3) T has trivial destructor and memcmp returns 0 (heuristic, however, I have never encountered a type where this is invalid) 
    121    *  4) rrlib_serialization is available and both objects are serialized to the same binary data (usually they are equal then) 
    122    */ 
    123   virtual bool Equals(const tGenericObject& other) const = 0; 
     94  ~tGenericObject() 
     95  { 
     96    type.DestructInstance(data); 
     97    data = nullptr; 
     98  } 
     99 
     100  // only allow casting to const base classes - everything else would be dangerous 
     101  operator const tTypedConstPointer&() const 
     102  { 
     103    return reinterpret_cast<const tTypedConstPointer&>(*this); 
     104  } 
     105  operator const tTypedPointer&() 
     106  { 
     107    return reinterpret_cast<const tTypedPointer&>(*this); 
     108  } 
     109 
     110  /*! 
     111   * Deep copy data to data pointed to by this pointer. 
     112   * A deep copy means that the destination object must not change if the source object is modified or deleted. 
     113   * Serialization of source and destination objects are equal after calling this. 
     114   * Caller must ensure that source and destination have the same (underlying) type and are not nullptr. 
     115   * 
     116   * \param source Pointer to data to be copied 
     117   * \throws May throw std::exception on invalid arguments or other failure 
     118   */ 
     119  inline void DeepCopyFrom(const tTypedConstPointer& source)  // only non-const for tGenericObject 
     120  { 
     121    reinterpret_cast<const tTypedPointer&>(*this).DeepCopyFrom(source); 
     122  } 
     123 
     124  /*! 
     125   * Deserialize data from input stream 
     126   * 
     127   * \param stream Input stream 
     128   * \throws Throws std::exception on invalid data in stream 
     129   */ 
     130  inline void Deserialize(serialization::tInputStream& stream)  // only non-const for tGenericObject 
     131  { 
     132    reinterpret_cast<const tTypedPointer&>(*this).Deserialize(stream); 
     133  } 
     134 
     135  /*! 
     136   * Deserialize data from input stream 
     137   * 
     138   * \param stream Input stream 
     139   * \throws Throws std::exception on invalid data in stream 
     140   */ 
     141  inline void Deserialize(serialization::tStringInputStream& stream)  // only non-const for tGenericObject 
     142  { 
     143    reinterpret_cast<const tTypedPointer&>(*this).Deserialize(stream); 
     144  } 
     145 
     146  /*! 
     147   * Deserialize data from XML node 
     148   * 
     149   * \param node XML node 
     150   * \throws Throws std::exception on invalid data in XML node 
     151   */ 
     152  void Deserialize(const xml::tNode& node)  // only non-const for tGenericObject 
     153  { 
     154    reinterpret_cast<const tTypedPointer&>(*this).Deserialize(node); 
     155  } 
     156 
     157  /*! 
     158   * Deserialize data from binary input stream - possibly using non-binary encoding. 
     159   * 
     160   * \param stream Binary input stream 
     161   * \param encoding Encoding to use 
     162   */ 
     163  void Deserialize(serialization::tInputStream& stream, serialization::tDataEncoding encoding)  // only non-const for tGenericObject 
     164  { 
     165    reinterpret_cast<const tTypedPointer&>(*this).Deserialize(stream, encoding); 
     166  } 
     167 
     168  /*! 
     169   * Returns whether data of two pointers is equal. 
     170   * Serializing equal objects must produce identical data. 
     171   * 
     172   * \param other Data to compare with 
     173   */ 
     174  bool Equals(const tTypedConstPointer& other) const 
     175  { 
     176    return reinterpret_cast<const tTypedConstPointer&>(*this).Equals(other); 
     177  } 
     178 
     179  /*! 
     180   * Same as Equals, but also returns true if only underlying types are equal. 
     181   * 
     182   * \param other Data to compare with 
     183   */ 
     184  bool EqualsUnderlying(const tTypedConstPointer& other) const 
     185  { 
     186    return reinterpret_cast<const tTypedConstPointer&>(*this).EqualsUnderlying(other); 
     187  } 
    124188 
    125189  /*! 
     
    127191   */ 
    128192  template <typename T> 
    129   const T& GetData() const 
    130   { 
    131     assert(typeid(T).name() == type.GetRttiName()); 
    132     return *static_cast<const T*>(wrapped); 
     193  inline const T& GetData() const 
     194  { 
     195    assert(typeid(typename NormalizedType<T>::type).name() == type.GetRttiName()); 
     196    return *static_cast<const T*>(data); 
    133197  } 
    134198 
     
    139203  inline T& GetData() 
    140204  { 
    141     assert(typeid(T).name() == type.GetRttiName()); 
    142     return *static_cast<T*>(wrapped); 
    143   } 
    144  
    145   /*! 
    146    * Raw void pointer to wrapped object 
     205    assert(typeid(typename NormalizedType<T>::type).name() == type.GetRttiName()); 
     206    return *static_cast<T*>(data); 
     207  } 
     208 
     209  /*! 
     210   * \return Raw void pointer to wrapped object 
    147211   */ 
    148212  inline void* GetRawDataPointer() 
    149213  { 
    150     return wrapped; 
    151   } 
    152  
    153   /*! 
    154    * Raw void pointer to wrapped object 
    155    */ 
     214    return data; 
     215  } 
    156216  inline const void* GetRawDataPointer() const 
    157217  { 
    158     return wrapped; 
    159   } 
    160  
    161   // Generic serialization 
    162   virtual void Deserialize(serialization::tInputStream& stream) = 0; 
    163   virtual void Deserialize(serialization::tStringInputStream& stream) = 0; 
    164 #ifdef _LIB_RRLIB_XML_PRESENT_ 
    165   virtual void Deserialize(const xml::tNode& node) = 0; 
    166 #endif 
    167   virtual void Serialize(serialization::tOutputStream& stream) const = 0; 
    168   virtual void Serialize(serialization::tStringOutputStream& stream) const = 0; 
    169 #ifdef _LIB_RRLIB_XML_PRESENT_ 
    170   virtual void Serialize(xml::tNode& node) const = 0; 
    171 #endif 
    172  
    173   /*! 
    174    * Deserialize data from binary input stream - possibly using non-binary encoding. 
    175    * 
    176    * \param is Binary input stream 
    177    * \param enc Encoding to use 
    178    */ 
    179   void Deserialize(serialization::tInputStream& stream, serialization::tDataEncoding enc); 
     218    return data; 
     219  } 
     220 
     221  /*! 
     222   * \ŗeturn Type information for object 
     223   */ 
     224  inline const tType& GetType() const 
     225  { 
     226    return type; 
     227  } 
     228 
     229  /*! 
     230   * Obtain element from vector. 
     231   * 
     232   * \param data Data pointer 
     233   * \param size Index of element 
     234   * \return 
     235   * - If this points to std::vector, returns &std::vector[index] 
     236   * - Otherwise, returns this object if index == 0 
     237   * \throws Throws std::invalid_argument if index is >= of what is returned by tGetVectorSize 
     238   */ 
     239  inline tTypedPointer GetVectorElement(size_t index) 
     240  { 
     241    return reinterpret_cast<const tTypedPointer&>(*this).GetVectorElement(index); 
     242  } 
     243  inline tTypedConstPointer GetVectorElement(size_t index) const 
     244  { 
     245    return reinterpret_cast<const tTypedPointer&>(*this).GetVectorElement(index); 
     246  } 
     247 
     248  /*! 
     249   * \param data Data pointer 
     250   * \return 
     251   * - If this points to std::vector, returns std::vector::size() 
     252   * - If nullptr, returns 0 
     253   * - Otherwise, returns 1 
     254   */ 
     255  inline size_t GetVectorSize() const 
     256  { 
     257    return reinterpret_cast<const tTypedConstPointer&>(*this).GetVectorSize(); 
     258  } 
     259 
     260  /*! 
     261   * Resizes std::vector. 
     262   * 
     263   * \param data Pointer to std::vector 
     264   * \param new_size New size 
     265   * \throws Throws std::invalid_argument 'data' does not point std::vector 
     266   */ 
     267  void ResizeVector(size_t new_size) 
     268  { 
     269    reinterpret_cast<const tTypedPointer&>(*this).ResizeVector(new_size); 
     270  } 
     271 
     272  /*! 
     273   * Serialize data 
     274   * 
     275   * \param target Target to serialize to (output stream or XML node) 
     276   */ 
     277  template <typename TTarget> 
     278  inline void Serialize(TTarget& target) const 
     279  { 
     280    reinterpret_cast<const tTypedConstPointer&>(*this).Serialize(target); 
     281  } 
    180282 
    181283  /*! 
    182284   * Serialize data to binary output stream - possibly using non-binary encoding. 
    183285   * 
    184    * \param os Binary output stream 
    185    * \param enc Encoding to use 
    186    */ 
    187   void Serialize(serialization::tOutputStream& stream, serialization::tDataEncoding enc) const; 
     286   * \param stream Binary output stream 
     287   * \param encoding Encoding to use 
     288   */ 
     289  void Serialize(serialization::tOutputStream& stream, serialization::tDataEncoding encoding) const 
     290  { 
     291    reinterpret_cast<const tTypedConstPointer&>(*this).Serialize(stream, encoding); 
     292  } 
     293 
     294  /*! 
     295   * \return String representation of object this points to. This is the serialized value for string serializable types. Otherwise it is type name + pointer. 
     296   */ 
     297  std::string ToString() const 
     298  { 
     299    return reinterpret_cast<const tTypedConstPointer&>(*this).ToString(); 
     300  } 
    188301 
    189302//---------------------------------------------------------------------- 
     
    192305protected: 
    193306 
    194   /*! Wrapped object */ 
    195   void* wrapped; 
    196  
    197  
    198   /*! 
    199    * \param wrapped Wrapped object 
    200    * \param dt Data Type of wrapped object 
    201    */ 
    202   tGenericObject(tType dt) : 
    203     wrapped() 
    204   { 
    205     this->type = dt; 
    206   } 
     307  friend class tType; 
     308 
     309  tGenericObject(void* pointer, const tType& type) : data(pointer), type(type) 
     310  { 
     311    assert((pointer == nullptr || (type.GetTypeTraits() & trait_flags::cTYPE_CLASSIFICATION_BITS) != static_cast<uint>(tTypeClassification::RPC_TYPE)) && "Only data types are valid"); 
     312  } 
     313 
     314  /*! Raw pointer to data/object */ 
     315  void* data; 
     316 
     317  /*! Runtime type information for the data/object that 'data' points to */ 
     318  tType type; 
    207319 
    208320//---------------------------------------------------------------------- 
     
    210322//---------------------------------------------------------------------- 
    211323private: 
    212  
    213   /*! 
    214    * Deep copy source object to this object 
    215    * (types MUST match) 
    216    * 
    217    * \param source Source object 
    218    */ 
    219   virtual void DeepCopyFrom(const void* source, tFactory* f) = 0; 
    220324 
    221325}; 
     
    227331} 
    228332 
     333#include "rrlib/rtti/tType.hpp" 
    229334 
    230335#endif 
Note: See TracChangeset for help on using the changeset viewer.