Skip to content

Commit

Permalink
Refs 16497. Refactor to link DataType lifecycle to their associated o…
Browse files Browse the repository at this point in the history
…bjects. Fixes issue #105

Signed-off-by: Miguel Barro <miguelbarro@eprosima.com>
  • Loading branch information
Miguel Barro committed Jan 26, 2023
1 parent d3134fe commit 9286d22
Show file tree
Hide file tree
Showing 17 changed files with 371 additions and 300 deletions.
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,10 @@ macro(compile_test)

compile_example(${TEST_NAME} SOURCE ${TEST_SOURCE})

if(MSVC)
target_compile_options(${TEST_NAME} PRIVATE /bigobj)
endif(MSVC)

target_link_libraries(${TEST_NAME}
PRIVATE
GTest::gtest
Expand Down
4 changes: 2 additions & 2 deletions include/xtypes/AliasType.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -177,9 +177,9 @@ class AliasType : public DynamicType

protected:

virtual DynamicType* clone() const override
std::shared_ptr<DynamicType> clone() const override
{
return new AliasType(*this);
return std::make_shared<AliasType>(*this);
}

private:
Expand Down
4 changes: 2 additions & 2 deletions include/xtypes/ArrayType.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -319,9 +319,9 @@ class ArrayType : public CollectionType

protected:

virtual DynamicType* clone() const override
std::shared_ptr<DynamicType> clone() const override
{
return new ArrayType(*this);
return std::make_shared<ArrayType>(*this);
}

private:
Expand Down
288 changes: 152 additions & 136 deletions include/xtypes/DynamicData.hpp

Large diffs are not rendered by default.

38 changes: 19 additions & 19 deletions include/xtypes/DynamicDataImpl.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ namespace xtypes {

#define DYNAMIC_DATA_NUMERIC_SIGNED_INT_SWITCH(MACRO, OPERATOR) \
{\
switch(type_.kind())\
switch(type_->kind())\
{\
case TypeKind::INT_8_TYPE:\
MACRO(int8_t, OPERATOR);\
Expand All @@ -39,14 +39,14 @@ namespace xtypes {
MACRO(int64_t, OPERATOR);\
default:\
xtypes_assert(false,\
"Operator" << #OPERATOR << "() isn't available for type '" << type_.name() << "'.");\
"Operator" << #OPERATOR << "() isn't available for type '" << type_->name() << "'.");\
return *this;\
}\
}

#define DYNAMIC_DATA_NUMERIC_INT_SWITCH(MACRO, OPERATOR) \
{\
switch(type_.kind())\
switch(type_->kind())\
{\
case TypeKind::UINT_8_TYPE:\
MACRO(uint8_t, OPERATOR);\
Expand All @@ -63,7 +63,7 @@ namespace xtypes {

#define DYNAMIC_DATA_NUMERIC_FLT_SWITCH(MACRO, OPERATOR) \
{\
switch(type_.kind())\
switch(type_->kind())\
{\
case TypeKind::FLOAT_32_TYPE:\
MACRO(float, OPERATOR);\
Expand All @@ -89,7 +89,7 @@ namespace xtypes {

#define DYNAMIC_DATA_BASICTYPE_SWITCH(MACRO, OPERATOR) \
{\
switch(type_.kind())\
switch(type_->kind())\
{\
case TypeKind::CHAR_8_TYPE:\
MACRO(char, OPERATOR);\
Expand All @@ -106,7 +106,7 @@ namespace xtypes {

#define DYNAMIC_DATA_BASICTYPE_INT_SWITCH(MACRO, OPERATOR) \
{\
switch(type_.kind())\
switch(type_->kind())\
{\
case TypeKind::CHAR_8_TYPE:\
MACRO(char, OPERATOR);\
Expand Down Expand Up @@ -236,29 +236,29 @@ inline std::string ReadableDynamicDataRef::to_string() const
template<>
inline std::string ReadableDynamicDataRef::cast<std::string>() const
{
xtypes_assert(type_.is_primitive_type() ||
type_.kind() == TypeKind::STRING_TYPE ||
type_.kind() == TypeKind::WSTRING_TYPE ||
type_.kind() == TypeKind::STRING16_TYPE ||
type_.is_enumerated_type(),
"Expected a primitive or string type but '" << type_.name() << "' received while casting data to 'std::string'.");
xtypes_assert(type_->is_primitive_type() ||
type_->kind() == TypeKind::STRING_TYPE ||
type_->kind() == TypeKind::WSTRING_TYPE ||
type_->kind() == TypeKind::STRING16_TYPE ||
type_->is_enumerated_type(),
"Expected a primitive or string type but '" << type_->name() << "' received while casting data to 'std::string'.");
// Custom switch-case statement for types not contained in the macros
switch (type_.kind())
switch (type_->kind())
{
case TypeKind::ENUMERATION_TYPE:
{
// For checking the associated_type, check for its memory_size
if (type_.memory_size() == sizeof(uint8_t))
if (type_->memory_size() == sizeof(uint8_t))
{
uint8_t temp = *this;
return std::to_string(temp);
}
else if (type_.memory_size() == sizeof(uint16_t))
else if (type_->memory_size() == sizeof(uint16_t))
{
uint16_t temp = *this;
return std::to_string(temp);
}
else if (type_.memory_size() == sizeof(uint32_t))
else if (type_->memory_size() == sizeof(uint32_t))
{
uint32_t temp = *this;
return std::to_string(temp);
Expand Down Expand Up @@ -347,7 +347,7 @@ inline DynamicData& DynamicData::operator -- ()

inline bool DynamicData::operator ! () const
{
switch(type_.kind())
switch(type_->kind())
{
case TypeKind::STRING_TYPE:
return this->value<std::string>().empty();
Expand Down Expand Up @@ -419,7 +419,7 @@ inline DynamicData DynamicData::operator OPERATOR (const ReadableDynamicDataRef&
#define DYNAMIC_DATA_NUMERIC_SAFE_OPERATOR_IMPLEMENTATION(OPERATOR)\
inline DynamicData DynamicData::operator OPERATOR (const ReadableDynamicDataRef& other) const \
{\
switch(type_.kind())\
switch(type_->kind())\
{\
case TypeKind::CHAR_8_TYPE:\
case TypeKind::CHAR_16_TYPE:\
Expand All @@ -428,7 +428,7 @@ inline DynamicData DynamicData::operator OPERATOR (const ReadableDynamicDataRef&
{\
std::ostringstream os;\
os << "Operator" << (#OPERATOR[0] == '^' ? "\\^" : #OPERATOR)\
<< " is not supported for type " << type_.name();\
<< " is not supported for type " << type_->name();\
throw std::runtime_error(os.str());\
}\
default:\
Expand Down
96 changes: 40 additions & 56 deletions include/xtypes/DynamicType.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,17 @@
#include <xtypes/TypeConsistency.hpp>

#include <string>
#include <memory>

namespace eprosima {
namespace xtypes {

class ReadableDynamicDataRef;
class SequenceInstance;

/// \brief Abstract base class for all dynamic types.
class DynamicType : public Instanceable
class DynamicType : public Instanceable,
public std::enable_shared_from_this<DynamicType>
{
public:

Expand Down Expand Up @@ -214,11 +219,14 @@ class DynamicType : public Instanceable

/// \brief Deep clone of the DynamicType.
/// \returns a new DynamicType without managing.
virtual DynamicType* clone() const = 0;
virtual std::shared_ptr<DynamicType> clone() const = 0;

TypeKind kind_;
std::string name_;

friend class ReadableDynamicDataRef;
friend class SequenceInstance;

public:

/// \brief Special managed pointer for DynamicTypes.
Expand All @@ -228,35 +236,39 @@ class DynamicType : public Instanceable
public:

/// \brief Default initialization without pointer any type.
Ptr()
: type_(nullptr)
{
}
Ptr() = default;

/// \brief Creates a copy of a DynamicType that will be managed.
/// The copy is avoid if DynamnicType is primitive.
Ptr(
const DynamicType& type)
: type_(dont_clone_type(&type) ? &type : type.clone())
Ptr(const DynamicType& type)
{
try
{
if(dont_clone_type(&type))
{
type_ = type.shared_from_this();
return;
}
}
catch(const std::bad_weak_ptr&) {}

// make a copy
type_ = type.clone();
}

/// \brief Copy constructor.
/// Makes an internal copy of the managed DynamicType.
/// The copy is avoid if DynamnicType is primitive.
Ptr(
const Ptr& ptr)
: type_(dont_clone_type(ptr.type_) ? ptr.type_ : ptr.type_->clone())
/// The copy is avoid if DynamicType is primitive.
Ptr(const Ptr& ptr)
{
}
if(!ptr.type_)
return;

Ptr(
Ptr&& ptr)
: type_(ptr.type_)
{
ptr.type_ = nullptr;
new (this) Ptr(*ptr.type_);
}

Ptr(Ptr&& ptr) = default;

Ptr& operator = (
const Ptr& ptr)
{
Expand All @@ -265,73 +277,45 @@ class DynamicType : public Instanceable
return *this;
}

reset();
type_ = dont_clone_type(ptr.type_) ? ptr.type_ : ptr.type_->clone();
type_ = dont_clone_type(ptr.type_.get()) ? ptr.type_ : ptr.type_->clone();
return *this;
}

Ptr& operator = (
Ptr&& ptr)
{
if (type_ == ptr.type_)
{
return *this;
}

reset();
type_ = ptr.type_;
ptr.type_ = nullptr;
return *this;
}
Ptr& operator = ( Ptr&& ptr) = default;

bool operator == (
const DynamicType::Ptr& ptr) const
{
return ptr.type_ == type_;
}

virtual ~Ptr()
{
reset();
}

/// \brief Remove the managed DynamicType and points to nothing.
void reset()
{
if (!dont_clone_type(type_))
{
delete type_;
}
type_ = nullptr;
}

/// \brief Free the internal managed DynamicType and points to nothing.
const DynamicType* free()
std::shared_ptr<const DynamicType> free()
{
const DynamicType* freed = type_;
type_ = nullptr;
std::shared_ptr<const DynamicType> freed;
type_.swap(freed);
return freed;
}

/// \brief Returns a pointer of the internal managed DynamicType.
/// \returns A pointer of the internal managed DynamicType.
const DynamicType* get() const
{
return type_;
return type_.get();
}

/// \brief Returns a pointer of the internal managed DynamicType.
/// \returns A pointer of the internal managed DynamicType.
const DynamicType* operator ->() const
{
return type_;
return type_.get();
}

/// \brief Get a non-const pointer of the internal managed DynamicType.
/// \returns A non-const pointer of the interal managed DynamicType
DynamicType* operator ->()
{
return const_cast<DynamicType*>(type_);
return const_cast<DynamicType*>(type_.get());
}

/// \brief Returns a reference of the intenral managed DynamicType.
Expand All @@ -343,7 +327,7 @@ class DynamicType : public Instanceable

private:

const DynamicType* type_;
std::shared_ptr<const DynamicType> type_;

static bool dont_clone_type(
const DynamicType* type)
Expand Down
19 changes: 10 additions & 9 deletions include/xtypes/EnumeratedType.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,19 +121,20 @@ class EnumeratedType : public PrimitiveType<T>
return consistency;
}

protected:
virtual DynamicType* clone() const override
{
EnumeratedType* result = new EnumeratedType<T>(PrimitiveType<T>::kind(), PrimitiveType<T>::name());
result->values_ = values_;
return result;
}

EnumeratedType(
TypeKind kind,
const std::string& name)
: PrimitiveType<T>(kind, name)
: PrimitiveType<T>(typename PrimitiveType<T>::use_function_primitive_type{}, kind, name)
{
}

protected:

std::shared_ptr<DynamicType> clone() const override
{
auto clon = std::make_shared<EnumeratedType>(this->kind(), this->name());
clon->values_ = values_;
return clon;
}

/// \brief Insert a enumerator into the enumerated.
Expand Down
Loading

0 comments on commit 9286d22

Please sign in to comment.