Browse Source

* Implemented storage to add data to the RTTI types

* Updated project structure
master
bergmann 5 years ago
parent
commit
0f1f448b10
40 changed files with 674 additions and 229 deletions
  1. +1
    -1
      .gitmodules
  2. +49
    -49
      CMakeLists.txt
  3. +3
    -0
      README.md
  4. +1
    -1
      cmake/Findcppcore.cmake
  5. +1
    -1
      cmake/Findcppmp.cmake
  6. +17
    -17
      cmake/cpprtti-const.cmake
  7. +9
    -21
      cmake/cpprtti-options.cmake
  8. +27
    -21
      cmake/cpprtti-var.cmake
  9. +1
    -1
      cmake/modules
  10. +2
    -0
      include/cpprtti.h
  11. +2
    -0
      include/cpprtti/misc.h
  12. +4
    -2
      include/cpprtti/misc/exception.h
  13. +7
    -2
      include/cpprtti/misc/helper.h
  14. +15
    -2
      include/cpprtti/misc/helper.inl
  15. +46
    -0
      include/cpprtti/misc/storage.h
  16. +61
    -0
      include/cpprtti/misc/storage.inl
  17. +39
    -5
      include/cpprtti/misc/variant.h
  18. +121
    -2
      include/cpprtti/misc/variant.inl
  19. +2
    -3
      include/cpprtti/registry.h
  20. +12
    -6
      include/cpprtti/registry.inl
  21. +0
    -2
      include/cpprtti/traits/default_type.h
  22. +2
    -0
      include/cpprtti/types.h
  23. +8
    -5
      include/cpprtti/types/class_type.h
  24. +16
    -0
      include/cpprtti/types/class_type.inl
  25. +0
    -2
      include/cpprtti/types/class_type_tpl.h
  26. +0
    -2
      include/cpprtti/types/fundamental_type.h
  27. +0
    -2
      include/cpprtti/types/fundamental_type_tpl.h
  28. +2
    -2
      include/cpprtti/types/member/member.h
  29. +1
    -2
      include/cpprtti/types/member/member_method.h
  30. +1
    -0
      include/cpprtti/types/member/member_method.inl
  31. +3
    -5
      include/cpprtti/types/member/member_variable.h
  32. +2
    -1
      include/cpprtti/types/member/member_variable.inl
  33. +36
    -3
      include/cpprtti/types/type.h
  34. +35
    -0
      include/cpprtti/types/type.inl
  35. +32
    -0
      include/cpprtti/types/type_decorator.h
  36. +39
    -0
      include/cpprtti/types/type_decorator.inl
  37. +27
    -28
      src/CMakeLists.txt
  38. +47
    -40
      test/CMakeLists.txt
  39. +2
    -1
      test/cpprtti/misc/variant_tests.cpp
  40. +1
    -0
      test/cpprtti/type/class_type_tests.cpp

+ 1
- 1
.gitmodules View File

@@ -1,3 +1,3 @@
[submodule "cmake/modules"]
path = cmake/modules
url = https://git.bergmann89.de/cpp/CmakeModules.git
url = b3rgmann@git.bergmann89.de:cpp/CMakeModules.git

+ 49
- 49
CMakeLists.txt View File

@@ -1,63 +1,63 @@
# Initialize CMake ################################################################################

CMake_Minimum_Required ( VERSION 3.12.0 FATAL_ERROR )
CMake_Minimum_Required ( VERSION 3.12.0 FATAL_ERROR )

# Set CMAKE_BUILD_TYPE
If ( NOT CMAKE_BUILD_TYPE )
Set ( CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build!" FORCE )
EndIf ( NOT CMAKE_BUILD_TYPE )
Set_Property ( CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS Debug Release RelWithDebInfo MinSizeRel )
If ( NOT CMAKE_BUILD_TYPE )
Set ( CMAKE_BUILD_TYPE "Release" CACHE STRING "Choose the type of build!" FORCE )
EndIf ( NOT CMAKE_BUILD_TYPE )
Set_Property ( CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS Debug Release RelWithDebInfo MinSizeRel )

# Set CMAKE_MODULE_PATH
If ( EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/cmake/" )
Set ( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/" )
EndIf ( )
If ( EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/cmake/" )
Set ( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules" )
EndIf ( )
If ( EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/cmake/" )
Set ( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/" )
EndIf ( )
If ( EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules/cmake" )
Set ( CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH}
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules/cmake" )
EndIf ( )

# Project #########################################################################################

Include ( GNUInstallDirs )
Include ( ${CMAKE_CURRENT_SOURCE_DIR}/cmake/cpprtti-options.cmake )
Include ( ${CMAKE_CURRENT_SOURCE_DIR}/cmake/cpprtti-const.cmake )
Include ( ${CMAKE_CURRENT_SOURCE_DIR}/cmake/cpprtti-var.cmake )
Project ( ${CPPRTTI_PROJECT_NAME}
DESCRIPTION "${CPPRTTI_PROJECT_DESCRIPTION}"
VERSION "${CPPRTTI_VERSION}" )
Include ( CTest )
Include ( GNUInstallDirs )
Include ( ${CMAKE_CURRENT_SOURCE_DIR}/cmake/cpprtti-options.cmake )
Include ( ${CMAKE_CURRENT_SOURCE_DIR}/cmake/cpprtti-const.cmake )
Include ( ${CMAKE_CURRENT_SOURCE_DIR}/cmake/cpprtti-var.cmake )
Project ( ${CPPRTTI_PROJECT_NAME}
DESCRIPTION "${CPPRTTI_PROJECT_DESCRIPTION}"
VERSION "${CPPRTTI_VERSION}" )
Include ( CTest )

# Subdirectories
Add_SubDirectory ( ${CMAKE_CURRENT_SOURCE_DIR}/src )
Add_SubDirectory ( ${CMAKE_CURRENT_SOURCE_DIR}/test )
Add_SubDirectory ( ${CMAKE_CURRENT_SOURCE_DIR}/src )
Add_SubDirectory ( ${CMAKE_CURRENT_SOURCE_DIR}/test )

# Install
If ( NOT CPPRTTI_HAS_EXPORT
OR NOT CPPRTTI_INSTALL_PACKAGE )
Return ( )
EndIf ( )

Include ( CMakePackageConfigHelpers )
Write_Basic_Package_Version_File ( "${CMAKE_CURRENT_BINARY_DIR}/cmake/cpprtti-config-version.cmake"
VERSION ${CPPRTTI_VERSION}
COMPATIBILITY AnyNewerVersion )
Configure_File ( "${CMAKE_CURRENT_SOURCE_DIR}/cmake/cpprtti-config.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/cmake/cpprtti-config.cmake"
@ONLY )

Set ( ConfigPackageLocation "${CPPRTTI_INSTALL_DIR_SHARE}/cmake" )
Install ( EXPORT
cpprtti
NAMESPACE
cpprtti::
DESTINATION
${ConfigPackageLocation} )
Install ( FILES
If ( NOT CPPRTTI_HAS_EXPORT
OR NOT CPPRTTI_INSTALL_PACKAGE )
Return ( )
EndIf ( )

Include ( CMakePackageConfigHelpers )
Write_Basic_Package_Version_File ( "${CMAKE_CURRENT_BINARY_DIR}/cmake/cpprtti-config-version.cmake"
VERSION ${CPPRTTI_VERSION}
COMPATIBILITY AnyNewerVersion )
Configure_File ( "${CMAKE_CURRENT_SOURCE_DIR}/cmake/cpprtti-config.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/cmake/cpprtti-config.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/cmake/cpprtti-config-version.cmake"
DESTINATION
${ConfigPackageLocation}
COMPONENT
Devel )
@ONLY )

Set ( ConfigPackageLocation "${CPPRTTI_INSTALL_DIR_SHARE}/cmake" )
Install ( EXPORT
cpprtti
NAMESPACE
cpprtti::
DESTINATION
${ConfigPackageLocation} )
Install ( FILES
"${CMAKE_CURRENT_BINARY_DIR}/cmake/cpprtti-config.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/cmake/cpprtti-config-version.cmake"
DESTINATION
${ConfigPackageLocation}
COMPONENT
Devel )

+ 3
- 0
README.md View File

@@ -0,0 +1,3 @@
# cpprtti

C++ run time type information library.

+ 1
- 1
cmake/Findcppcore.cmake View File

@@ -25,7 +25,7 @@ If ( NOT ${CHECKOUT_RET} EQUAL 0 )
EndIf ( )

# Include Cloned Repository
Include ( ${CMAKE_CURRENT_LIST_DIR}/modules/find_local_module.cmake )
Include ( ${CMAKE_CURRENT_LIST_DIR}/modules/cmake/find_local_module.cmake )
FindLocalModule ( cppcore ${CPPCORE_CHECKOUT_DIR} )

# Create Alias Targets


+ 1
- 1
cmake/Findcppmp.cmake View File

@@ -25,7 +25,7 @@ If ( NOT ${CHECKOUT_RET} EQUAL 0 )
EndIf ( )

# Include Cloned Repository
Include ( ${CMAKE_CURRENT_LIST_DIR}/modules/find_local_module.cmake )
Include ( ${CMAKE_CURRENT_LIST_DIR}/modules/cmake/find_local_module.cmake )
FindLocalModule ( cppmp ${CPPMP_CHECKOUT_DIR} )

# Create Alias Targets


+ 17
- 17
cmake/cpprtti-const.cmake View File

@@ -1,28 +1,28 @@
# This file contains constant variables that are fixed to this project

# Version
Set ( CPPRTTI_VERSION_MAJOR 1 )
Set ( CPPRTTI_VERSION_MINOR 0 )
Set ( CPPRTTI_VERSION_PATCH 0 )
Set ( CPPRTTI_VERSION_BUILD 0 )
Set ( CPPRTTI_VERSION_HASH "" )
Set ( CPPRTTI_VERSION_BEHIND 0 )
Set ( CPPRTTI_VERSION_DIRTY 0 )
Set ( CPPRTTI_VERSION_MAJOR 1 )
Set ( CPPRTTI_VERSION_MINOR 0 )
Set ( CPPRTTI_VERSION_PATCH 0 )
Set ( CPPRTTI_VERSION_BUILD 0 )
Set ( CPPRTTI_VERSION_HASH "" )
Set ( CPPRTTI_VERSION_BEHIND 0 )
Set ( CPPRTTI_VERSION_DIRTY 0 )

# Names
Set ( CPPRTTI_PROJECT_NAME "cpprtti" )
Set ( CPPRTTI_PROJECT_DESCRIPTION "A simple hello world library" )
Set ( CPPRTTI_PROJECT_NAME "cpprtti" )
Set ( CPPRTTI_PROJECT_DESCRIPTION "C++ run time type information library" )

# Include generated variables for further usage
Include ( ${CMAKE_CURRENT_LIST_DIR}/cpprtti-var.cmake )
Include ( ${CMAKE_CURRENT_LIST_DIR}/cpprtti-var.cmake )

# Install directories
Set ( CPPRTTI_INSTALL_DIR_INCLUDE "${CMAKE_INSTALL_INCLUDEDIR}/${CPPRTTI_NAME}" )
Set ( CPPRTTI_INSTALL_DIR_LIB "${CMAKE_INSTALL_LIBDIR}" )
Set ( CPPRTTI_INSTALL_DIR_SHARE "${CMAKE_INSTALL_DATAROOTDIR}/${CPPRTTI_NAME}" )
Set ( CPPRTTI_INSTALL_DIR_INCLUDE "${CMAKE_INSTALL_INCLUDEDIR}/${CPPRTTI_NAME}" )
Set ( CPPRTTI_INSTALL_DIR_LIB "${CMAKE_INSTALL_LIBDIR}" )
Set ( CPPRTTI_INSTALL_DIR_SHARE "${CMAKE_INSTALL_DATAROOTDIR}/${CPPRTTI_NAME}" )

# C Standard
Set ( CMAKE_C_STANDARD 11 )
Set ( CMAKE_CXX_STANDARD 17 )
Set ( CMAKE_C_STANDARD_REQUIRED ON )
Set ( CMAKE_CXX_STANDARD_REQUIRED ON )
Set ( CMAKE_C_STANDARD 11 )
Set ( CMAKE_CXX_STANDARD 17 )
Set ( CMAKE_C_STANDARD_REQUIRED ON )
Set ( CMAKE_CXX_STANDARD_REQUIRED ON )

+ 9
- 21
cmake/cpprtti-options.cmake View File

@@ -1,23 +1,11 @@
# This file contains options that can be passed to the cmake command

Option ( CPPRTTI_INSTALL_HEADER
"Install headers of cpprtti."
ON )
Option ( CPPRTTI_INSTALL_STATIC
"Install static library of cpprtti."
ON )
Option ( CPPRTTI_INSTALL_SHARED
"Install shared library of cpprtti."
ON )
Option ( CPPRTTI_INSTALL_DEBUG
"Install the stripped debug informations of cpprtti."
OFF )
Option ( CPPRTTI_INSTALL_PACKAGE
"Install the cmake package of cpprtti."
ON )
Option ( CPPRTTI_NO_STRIP
"Do not strip debug symbols from binary."
OFF )
Option ( CPPRTTI_USE_GIT_VERSION
"Read the git tags to get the version of cpprtti"
ON )
Option ( CPPRTTI_INSTALL_HEADER
"Install headers of cpprtti."
ON )
Option ( CPPRTTI_INSTALL_PACKAGE
"Install the cmake package of cpprtti."
ON )
Option ( CPPRTTI_USE_GIT_VERSION
"Read the git tags to get the version of cpprtti"
ON )

+ 27
- 21
cmake/cpprtti-var.cmake View File

@@ -1,26 +1,32 @@
# This file contains generated variables that are needed for the project

# Git Version
If ( CPPRTTI_USE_GIT_VERSION )
Include ( git_helper OPTIONAL RESULT_VARIABLE HAS_GIT_HELPER )
If ( HAS_GIT_HELPER )
GitGetVersion ( ${CMAKE_CURRENT_LIST_DIR}/..
CPPRTTI_VERSION_MAJOR
CPPRTTI_VERSION_MINOR
CPPRTTI_VERSION_PATCH
CPPRTTI_VERSION_BUILD
CPPRTTI_VERSION_HASH
CPPRTTI_VERSION_BEHIND
CPPRTTI_VERSION_DIRTY )
EndIf ( )
EndIf ( )
If ( CPPRTTI_USE_GIT_VERSION )
Include ( git_helper OPTIONAL RESULT_VARIABLE HAS_GIT_HELPER )
If ( HAS_GIT_HELPER )
GitGetVersion ( ${CMAKE_CURRENT_LIST_DIR}/..
CPPRTTI_VERSION_MAJOR
CPPRTTI_VERSION_MINOR
CPPRTTI_VERSION_PATCH
CPPRTTI_VERSION_BUILD
CPPRTTI_VERSION_HASH
CPPRTTI_VERSION_BEHIND
CPPRTTI_VERSION_DIRTY )
EndIf ( )
EndIf ( )

# Strings
Set ( CPPRTTI_VERSION_SHORT "${CPPRTTI_VERSION_MAJOR}.${CPPRTTI_VERSION_MINOR}" )
Set ( CPPRTTI_VERSION "${CPPRTTI_VERSION_SHORT}.${CPPRTTI_VERSION_PATCH}.${CPPRTTI_VERSION_BUILD}" )
Set ( CPPRTTI_VERSION_COMPLETE "${CPPRTTI_VERSION}" )
Set ( CPPRTTI_NAME "${CPPRTTI_PROJECT_NAME}-${CPPRTTI_VERSION_SHORT}" )
Set ( CPPRTTI_OUTPUTNAME "${CPPRTTI_PROJECT_NAME}" )
If ( CPPRTTI_VERSION_BEHIND )
Set ( CPPRTTI_VERSION_COMPLETE "${CPPRTTI_VERSION_COMPLETE}+${CPPRTTI_VERSION_BEHIND}" )
EndIf ( )
Set ( CPPRTTI_VERSION_SHORT
"${CPPRTTI_VERSION_MAJOR}.${CPPRTTI_VERSION_MINOR}" )
Set ( CPPRTTI_VERSION
"${CPPRTTI_VERSION_SHORT}.${CPPRTTI_VERSION_PATCH}.${CPPRTTI_VERSION_BUILD}" )
Set ( CPPRTTI_VERSION_COMPLETE
"${CPPRTTI_VERSION}" )
Set ( CPPRTTI_NAME
"${CPPRTTI_PROJECT_NAME}-${CPPRTTI_VERSION_SHORT}" )
Set ( CPPRTTI_OUTPUTNAME
"${CPPRTTI_PROJECT_NAME}" )
If ( CPPRTTI_VERSION_BEHIND )
Set ( CPPRTTI_VERSION_COMPLETE
"${CPPRTTI_VERSION_COMPLETE}+${CPPRTTI_VERSION_BEHIND}" )
EndIf ( )

+ 1
- 1
cmake/modules

@@ -1 +1 @@
Subproject commit ebbae4fbb42d671331b4c6e9d1d142f41dcacc1b
Subproject commit 94b9877d65e46c9d8169ebc46f163d02e4d9dcf3

+ 2
- 0
include/cpprtti.h View File

@@ -4,3 +4,5 @@
#include <cpprtti/registry.h>
#include <cpprtti/traits.h>
#include <cpprtti/types.h>

#include <cpprtti/registry.inl>

+ 2
- 0
include/cpprtti/misc.h View File

@@ -2,8 +2,10 @@

#include "misc/exception.h"
#include "misc/helper.h"
#include "misc/storage.h"
#include "misc/variant.h"

#include "misc/exception.inl"
#include "misc/helper.inl"
#include "misc/storage.inl"
#include "misc/variant.inl"

+ 4
- 2
include/cpprtti/misc/exception.h View File

@@ -23,11 +23,15 @@ namespace cpprtti
/* variant */
variant_error = 2000,
variant_is_empty, //!< The variant does not store any value!
variant_is_const, //!< The value stored in the variant is const!
variant_type_mismatch, //!< The variant does not store the requested type!
variant_invalid_cast, //!< The value stored in the variant could not be cast to the requested type!
variant_convert_to, //!< No known conversion for the passed types.
variant_assign, //!< Variant is not copy assignable.

/* class */
class_error = 3000,
class_member_does_not_exist, //!< The requested member does not exist.
class_member_already_exists, //!< Unable to create member: Name is already in use!
class_type_mismatch, //!< Type does not match the.
class_member_not_readable, //!< Member variable is not readable!
@@ -72,5 +76,3 @@ namespace cpprtti
};

}

#include "exception.inl"

+ 7
- 2
include/cpprtti/misc/helper.h View File

@@ -7,6 +7,13 @@ namespace cpprtti
{

using type_id = size_t;
using storage_id = size_t;

/**
* @brief Get the ID of a certain C++ storage class.
*/
template<typename X>
inline storage_id get_storage_id();

/**
* @brief Get the ID of a certain C++ type.
@@ -21,5 +28,3 @@ namespace cpprtti
inline const std::string& get_type_name();

}

#include "helper.inl"

+ 15
- 2
include/cpprtti/misc/helper.inl View File

@@ -10,7 +10,11 @@ namespace cpprtti
namespace __impl
{

inline type_id create_type_id()
struct tag_type_id { };
struct tag_storage_id { };

template<typename...>
inline type_id create_id()
{
static type_id value { };
return ++value;
@@ -26,10 +30,19 @@ namespace cpprtti

}

template<typename X>
storage_id get_storage_id()
{
using namespace __impl;
static const auto value = create_id<tag_storage_id>();
return value;
}

template<typename X>
type_id get_type_id()
{
static const auto value = __impl::create_type_id();
using namespace __impl;
static const auto value = create_id<tag_type_id>();
return value;
}



+ 46
- 0
include/cpprtti/misc/storage.h View File

@@ -0,0 +1,46 @@
#pragma once

#include <memory>
#include <vector>

#include "helper.h"

namespace cpprtti
{

struct storage_container
{
private:
using item_ptr_s = std::shared_ptr<void>;
using item_vector = std::vector<item_ptr_s>;

private:
item_vector _items;

public:
/**
* @brief Get the requested storage or nullptr if the storage does not exist.
*/
template<typename T>
T* storage();

/**
* @brief Get the requested storage or nullptr if the storage does not exist.
*/
template<typename T>
T* storage(bool can_create);

/**
* @brief Create a new storage.
*/
template<typename T>
T* storage(const std::shared_ptr<T>& item);

/**
* @brief Get the requested storage or nullptr if the storage does not exist.
*/
template<typename T>
const T* storage() const;
};

}

+ 61
- 0
include/cpprtti/misc/storage.inl View File

@@ -0,0 +1,61 @@
#pragma once

#include <cppmp/core/modifier.h>

#include "storage.h"

namespace cpprtti
{

/* storage_container */

template<typename T>
T* storage_container::storage()
{
using storage_type = cppmp::decay_t<T>;
auto id = get_storage_id<storage_type>();
return (id < _items.size())
? static_cast<storage_type*>(_items[id].get())
: nullptr;
}

template<typename T>
T* storage_container::storage(bool can_create)
{
using storage_type = cppmp::decay_t<T>;
auto id = get_storage_id<storage_type>();
if ( can_create
&& ( id >= _items.size()
|| !_items[id]))
{
_items.resize(id + 1);
_items[id] = std::make_shared<storage_type>();
}
return (id < _items.size())
? static_cast<storage_type*>(_items[id].get())
: nullptr;
}

template<typename T>
T* storage_container::storage(const std::shared_ptr<T>& item)
{
using storage_type = cppmp::decay_t<T>;
auto id = get_storage_id<storage_type>();
_items.resize(id + 1);
_items[id] = item;
return (id < _items.size())
? static_cast<storage_type*>(_items[id].get())
: nullptr;
}

template<typename T>
const T* storage_container::storage() const
{
using storage_type = cppmp::decay_t<T>;
auto id = get_storage_id<storage_type>();
return (id < _items.size())
? static_cast<storage_type*>(_items[id].get())
: nullptr;
}

}

+ 39
- 5
include/cpprtti/misc/variant.h View File

@@ -5,11 +5,13 @@
#include <cppmp/misc/generic_predicate.h>

#include "helper.h"
#include "../types/type.h"

namespace cpprtti
{

struct type;
struct variant;

namespace __impl
{

@@ -22,18 +24,36 @@ namespace cpprtti

struct variant_impl
{
public:
const type& type;
void * data { nullptr };
bool is_const { false };
bool is_reference { false };

public:
/**
* @brief Constructor.
*/
inline variant_impl(const cpprtti::type& p_type);

/**
* @brief Destructor.
*/
virtual ~variant_impl() = default;

/**
* @brief Assign a new value.
*/
inline void assign(const variant& v);

private:
/**
* @brief Actual implementation of the assign method.
*/
virtual void assign_impl(const variant& v) = 0;
};

using variant_impl_ptr_s = std::shared_ptr<const variant_impl>;
using variant_impl_ptr_s = std::shared_ptr<variant_impl>;

}

@@ -81,7 +101,23 @@ namespace cpprtti
/**
* @brief Check if the variant contains a value.
*/
inline bool empty();
inline bool empty() const;

/**
* @brief Convert this variant to another type.
*/
template<typename T_to>
inline variant to() const;

/**
* @brief Convert this variant to another type.
*/
inline variant to(const cpprtti::type& t) const;

/**
* @brief Assign the value of this variant from another variant.
*/
inline void assign(const variant& v);

/**
* @brief Check if the variant contains a value.
@@ -98,5 +134,3 @@ namespace cpprtti
constexpr decltype(auto) make_variant = cppmp::generic_predicate<__impl::variant_builder> { };

}

#include "variant.inl"

+ 121
- 2
include/cpprtti/misc/variant.inl View File

@@ -2,6 +2,7 @@

#include <cppcore/misc/string_builder.h>

#include <cppmp/core/types.h>
#include <cppmp/core/checker.h>
#include <cppmp/core/modifier.h>
#include <cppmp/core/conditionals.h>
@@ -24,6 +25,44 @@ namespace cpprtti
: type(p_type)
{ }

void variant_impl::assign(const variant& v)
{
if (is_const)
{
throw exception(
error_code::variant_is_const,
"The value stored in the variant is const!");
}

if (v.empty())
{
throw exception(
error_code::variant_is_empty,
"The passed variant does not store any value!");
}

if (type.id() != v.type().id())
{
auto converter = v.type().convert_to(type.id());
if (!converter)
{
throw exception(
error_code::variant_convert_to,
cppcore::string_builder()
<< "No known conversion from type '"
<< v.type().name()
<< "' to type '"
<< type.name()
<< "'!");
}
this->assign_impl((*converter)(v));
}
else
{
this->assign_impl(v);
}
}

/* variant_builder - default */

template<typename X, typename>
@@ -61,6 +100,11 @@ namespace cpprtti
is_const = cppmp::is_const_v<cppmp::remove_reference_t<T>>;
is_reference = false;
}

void assign_impl(const variant& v) override
{
*static_cast<cppmp::decay_t<T>*>(data) = v.get<const T&>();
};
};

template<typename X_registry, typename X>
@@ -94,6 +138,30 @@ namespace cpprtti
is_const = cppmp::is_const_v<cppmp::remove_reference_t<T>>;
is_reference = true;
}

void assign_impl(const variant& v) override
{

};

template<typename X = cppmp::decay_t<T>>
cppmp::enable_if_t<cppmp::is_copy_assignable_v<X>>
assign_helper(const variant& v)
{
*static_cast<cppmp::decay_t<T>*>(data) = v.get<const T&>();
}

template<typename X = cppmp::decay_t<T>>
cppmp::enable_if_t<!cppmp::is_copy_assignable_v<X>>
assign_helper(const variant& v)
{
throw exception(
error_code::variant_assign,
cppcore::string_builder()
<< "Value of type '"
<< type.name()
<< "' is not copy assignable!");
}
};

template<typename X_registry, typename X>
@@ -121,6 +189,19 @@ namespace cpprtti
{ return std::forward<X>(x); }
};

/* variant_builder - type, variant (convert_from) */

template<typename T_registry, typename... T_args>
struct variant_builder<
cppmp::list<T_registry, const type&, T_args...>,
void
>
{
template<typename X_registry, typename... X_args>
static constexpr decltype(auto) apply(X_registry& p_registry, const type& t, X_args&&... args)
{ return make_variant(std::forward<X_args>(args)...).to(t.id()); }
};

/* value_extractor - default */

template<typename X, typename = void>
@@ -234,12 +315,50 @@ namespace cpprtti
<< ")");
}

return __impl::extract_value(*_impl, cppmp::type_v<T>);
auto& impl = static_cast<const __impl::variant_impl&>(*_impl);
return __impl::extract_value(impl, cppmp::type_v<T>);
}

bool variant::empty()
bool variant::empty() const
{ return !static_cast<bool>(_impl); }

template<typename T_to>
variant variant::to() const
{
using to_type = cppmp::decay_t<T_to>;
return to(get_type_id<to_type>());
}

variant variant::to(const cpprtti::type& t) const
{
check_impl();

auto& type = _impl->type;
if (t.id() == type.id())
return *this;

auto* converter = type.convert_to(t.id());
if (!converter)
{
throw exception(
error_code::variant_is_empty,
cppcore::string_builder()
<< "No known conversion from type '"
<< type.name()
<< "' to type '"
<< t.name()
<< "'!");
}

return (*converter)(*this);
}

inline void variant::assign(const variant& v)
{
check_impl();
_impl->assign(v);
}

variant::operator bool() const
{ return static_cast<bool>(_impl); }



+ 2
- 3
include/cpprtti/registry.h View File

@@ -4,6 +4,7 @@
#include <memory>

#include "types/type.h"
#include "types/type_decorator.h"

namespace cpprtti
{
@@ -88,9 +89,7 @@ namespace cpprtti
* @brief Create a new type for the passed C++ type with the passed implementation type.
*/
template<typename T_impl>
inline T_impl& create();
inline type_decorator<T_impl>& create();
};

}

#include "registry.inl"

+ 12
- 6
include/cpprtti/registry.inl View File

@@ -18,7 +18,8 @@ namespace cpprtti
template<typename T_type>
const auto& registry::get() const
{
using impl_type = default_type_t<T_type>;
using impl_type = default_type_t<T_type>;
using decorated_type = type_decorator<impl_type>;

auto * t = find<T_type>();

@@ -31,7 +32,7 @@ namespace cpprtti
<< get_type_name<T_type>());
}

auto * ret = dynamic_cast<const impl_type *>(t);
auto * ret = dynamic_cast<const decorated_type *>(t);
if (!ret)
{
throw exception(
@@ -47,11 +48,14 @@ namespace cpprtti
template<typename T_type, typename T_impl>
auto& registry::get()
{
using impl_type = T_impl;
using decorated_type = type_decorator<impl_type>;

auto * t = find<T_type>();
if (!t)
t = &create<T_impl>();
t = &create<impl_type>();

auto * ret = dynamic_cast<T_impl *>(t);
auto * ret = dynamic_cast<decorated_type *>(t);
if (!ret)
{
throw exception(
@@ -105,9 +109,11 @@ namespace cpprtti
}

template<typename T_impl>
T_impl& registry::create()
type_decorator<T_impl>& registry::create()
{
auto impl = std::make_shared<T_impl>(*this);
using decorated_type = type_decorator<T_impl>;

auto impl = std::make_shared<decorated_type>(*this);

auto id_it = _id_map.find(impl->id());
if (id_it != _id_map.end())


+ 0
- 2
include/cpprtti/traits/default_type.h View File

@@ -10,5 +10,3 @@ namespace cpprtti
using default_type_t = typename default_type_trait<cppmp::decay_t<T>>::type;

}

#include "default_type.inl"

+ 2
- 0
include/cpprtti/types.h View File

@@ -5,10 +5,12 @@
#include "types/fundamental_type_tpl.h"
#include "types/fundamental_type.h"
#include "types/member.h"
#include "types/type_decorator.h"
#include "types/type.h"

#include "types/class_type_tpl.inl"
#include "types/class_type.inl"
#include "types/fundamental_type_tpl.inl"
#include "types/fundamental_type.inl"
#include "types/type_decorator.inl"
#include "types/type.inl"

+ 8
- 5
include/cpprtti/types/class_type.h View File

@@ -31,13 +31,18 @@ namespace cpprtti
/**
* @brief Get a map of all registered members.
*/
const member_map& members() const;
inline const member& member(const std::string& p_name) const;

/**
* @brief Get a map of all registered members.
*/
inline const member_map& members() const;

/**
* @brief Register a new member variable.
*/
template<typename... T_args>
auto& add_member_variable(
inline auto& add_member_variable(
const std::string& p_name,
T_args&&... p_args);

@@ -45,11 +50,9 @@ namespace cpprtti
* @brief Register a new member method.
*/
template<typename... T_args>
auto& add_member_method(
inline auto& add_member_method(
const std::string& p_name,
T_args&&... p_args);
};

}

#include "class_type.inl"

+ 16
- 0
include/cpprtti/types/class_type.inl View File

@@ -16,6 +16,22 @@ namespace cpprtti
: type(p_registry, p_id, p_name, rtti_type_t::class_type)
{ }

const member& class_type::member(
const std::string& p_name) const
{
auto it = _members.find(p_name);
if (it == _members.end())
{
throw exception(
error_code::class_member_does_not_exist,
cppcore::string_builder()
<< "Member with the name '"
<< p_name
<< "' does not exists");
}
return *it->second;
}

const class_type::member_map& class_type
::members() const
{ return _members; }


+ 0
- 2
include/cpprtti/types/class_type_tpl.h View File

@@ -21,5 +21,3 @@ namespace cpprtti
};

}

#include "class_type_tpl.inl"

+ 0
- 2
include/cpprtti/types/fundamental_type.h View File

@@ -19,5 +19,3 @@ namespace cpprtti
};

}

#include "fundamental_type.inl"

+ 0
- 2
include/cpprtti/types/fundamental_type_tpl.h View File

@@ -21,5 +21,3 @@ namespace cpprtti
};

}

#include "fundamental_type_tpl.inl"

+ 2
- 2
include/cpprtti/types/member/member.h View File

@@ -3,6 +3,7 @@
#include <string>

#include "../../types/type.h"
#include "../../misc/storage.h"

namespace cpprtti
{
@@ -15,6 +16,7 @@ namespace cpprtti
};

struct member
: public storage_container
{
protected:
cpprtti::type& _owner;
@@ -52,5 +54,3 @@ namespace cpprtti
};

}

#include "member.inl"

+ 1
- 2
include/cpprtti/types/member/member_method.h View File

@@ -3,6 +3,7 @@
#include <cppmp/misc/generic_predicate.h>

#include "member.h"
#include "../../misc/variant.h"

namespace cpprtti
{
@@ -42,5 +43,3 @@ namespace cpprtti
constexpr decltype(auto) make_member_method = cppmp::generic_predicate<__impl::member_method_builder> { };

}

#include "member_method.inl"

+ 1
- 0
include/cpprtti/types/member/member_method.inl View File

@@ -3,6 +3,7 @@
#include <cppmp/traits/lambda_traits.h>

#include "member_method.h"
#include "../../misc/variant.h"

namespace cpprtti
{


+ 3
- 5
include/cpprtti/types/member/member_variable.h View File

@@ -36,17 +36,17 @@ namespace cpprtti
/**
* @brief RTTI type of that member represents.
*/
const cpprtti::type& type() const;
inline const cpprtti::type& type() const;

/**
* @brief Check if the variable is readable.
*/
bool is_readale() const;
inline bool is_readale() const;

/**
* @brief Check if the variable is writable.
*/
bool is_writable() const;
inline bool is_writable() const;

/**
* @brief Get the current value of the member.
@@ -75,5 +75,3 @@ namespace cpprtti
constexpr decltype(auto) make_member_variable = cppmp::generic_predicate<__impl::member_variable_builder> { };

}

#include "member_variable.inl"

+ 2
- 1
include/cpprtti/types/member/member_variable.inl View File

@@ -86,7 +86,8 @@ namespace cpprtti

static constexpr decltype(auto) is_read_only_v =
cppmp::is_const_v<cppmp::remove_reference_t<object_type>>
|| cppmp::is_const_v<cppmp::remove_reference_t<value_type>>;
|| cppmp::is_const_v<cppmp::remove_reference_t<value_type>>
|| !cppmp::is_copy_assignable_v<value_type>;
};

/* setter_info_trait */


+ 36
- 3
include/cpprtti/types/type.h View File

@@ -1,8 +1,12 @@
#pragma once

#include <map>
#include <string>
#include <functional>

#include <cpprtti/misc/helper.h>
#include <cpprtti/misc/variant.h>
#include <cpprtti/misc/storage.h>

namespace cpprtti
{
@@ -22,12 +26,21 @@ namespace cpprtti
* @brief represents any C++ type
*/
struct type
: public storage_container
{
public:
using converter = std::function<variant(variant)>;
using converter_map = std::map<type_id, converter>;

template<typename T_base>
friend struct type_decorator;

protected:
cpprtti::registry& _registry; //!< Type registry this type belongs to.
type_id _id; //!< Unique ID
std::string _name; //!< Name of the type.
rtti_type_t _rtti_type; //!< Type specialization
rtti_type_t _rtti_type; //!< Type specialization.
converter_map _converters; //!< Convert this type to another type.

public:
/**
@@ -68,8 +81,28 @@ namespace cpprtti
* @brief Get the RTTI type of this type object.
*/
inline rtti_type_t rtti_type() const;

/**
* @brief Get a converter that can convert this type to the passed type.
*/
template<typename T_to>
inline const converter* convert_to() const;

/**
* @brief Get a converter that can convert this type to the passed type ID.
*/
inline const converter* convert_to(type_id id) const;

/**
* @brief Get a converter that can convert the passed type to this type.
*/
template<typename T_from>
inline const converter* convert_from() const;

/**
* @brief Get a converter that can convert the passed type ID to this type.
*/
inline const converter* convert_from(type_id id) const;
};

}

#include "type.inl"

+ 35
- 0
include/cpprtti/types/type.inl View File

@@ -1,6 +1,7 @@
#pragma once

#include "type.h"
#include "../registry.h"

namespace cpprtti
{
@@ -33,4 +34,38 @@ namespace cpprtti
rtti_type_t type::rtti_type() const
{ return _rtti_type; }

template<typename T_to>
const type::converter* type::convert_to() const
{
using to_type = cppmp::decay_t<T_to>;
return convert_to(get_type_id<to_type>());
}

const type::converter* type::convert_to(type_id id) const
{
auto it = _converters.find(id);
return it == _converters.end()
? nullptr
: &it->second;
}

template<typename T_from>
const type::converter* type::convert_from() const
{
using from_type = cppmp::decay_t<T_from>;
return convert_from(get_type_id<from_type>());
}

const type::converter* type::convert_from(type_id id) const
{
auto* type = _registry.find(id);
if (!type)
return nullptr;

auto it = type->_converters.find(this->_id);
return it == type->_converters.end()
? nullptr
: &it->second;
}

}

+ 32
- 0
include/cpprtti/types/type_decorator.h View File

@@ -0,0 +1,32 @@
#pragma once

#include "type.h"

namespace cpprtti
{

template<typename T_base>
struct type_decorator
: public T_base
{
public:
using base_type = T_base;
using converter = typename type::converter;

public:
using base_type::base_type;

/**
* @brief Set the converter that can convert this type to the passed type.
*/
template<typename T_to>
inline auto& convert_to(const converter& p_converter);

/**
* @brief Set the converter that can convert the passed type to this type.
*/
template<typename T_from>
inline auto& convert_from(const converter& p_converter);
};

}

+ 39
- 0
include/cpprtti/types/type_decorator.inl View File

@@ -0,0 +1,39 @@
#pragma once

#include <cppmp/core/modifier.h>

#include "type_decorator.h"
#include "../misc/helper.h"

namespace cpprtti
{

/* type_decorator */

template<typename T_base>
template<typename T_to>
auto& type_decorator<T_base>
::convert_to(const converter& p_converter)
{
using to_type = cppmp::decay_t<T_to>;

auto id = get_type_id<to_type>();
this->_converters[id] = p_converter;

return *this;
}

template<typename T_base>
template<typename T_from>
auto& type_decorator<T_base>
::convert_from(const converter& p_converter)
{
using from_type = T_from;

auto& type = this->_registry.template get<from_type>();
type._converters[this->_id] = p_converter;

return *this;
}

}

+ 27
- 28
src/CMakeLists.txt View File

@@ -1,38 +1,37 @@
# Initialize ######################################################################################

Include ( cotire OPTIONAL RESULT_VARIABLE HAS_COTIRE )
Include ( pedantic OPTIONAL RESULT_VARIABLE HAS_PEDANTIC )
Include ( strip_symbols OPTIONAL RESULT_VARIABLE HAS_STRIP_SYMBOLS )
Include ( cotire OPTIONAL RESULT_VARIABLE HAS_COTIRE )
Include ( pedantic OPTIONAL RESULT_VARIABLE HAS_PEDANTIC )
Include ( strip_symbols OPTIONAL RESULT_VARIABLE HAS_STRIP_SYMBOLS )

Find_Package ( cppcore )
Find_Package ( cppmp )
Find_Package ( cppmp )
Find_Package ( cppcore )

# Object Library ##################################################################################
# Interface Library ###############################################################################

Set ( CPPRTTI_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../include )
Add_Library ( cpprtti
INTERFACE )
Target_Include_Directories ( cpprtti
INTERFACE
$<BUILD_INTERFACE:${CPPRTTI_INCLUDE_DIR}>
$<INSTALL_INTERFACE:${CPPRTTI_INSTALL_DIR_INCLUDE}> )
Target_Link_Libraries ( cpprtti
INTERFACE
cppcore
cppmp )
Set ( CPPRTTI_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../include )
Add_Library ( cpprtti INTERFACE )
Target_Include_Directories ( cpprtti
INTERFACE
$<BUILD_INTERFACE:${CPPRTTI_INCLUDE_DIR}>
$<INSTALL_INTERFACE:${CPPRTTI_INSTALL_DIR_INCLUDE}> )
Target_Link_Libraries ( cpprtti
INTERFACE
cppmp
cppcore )

# Install #########################################################################################

Set ( CPPRTTI_HAS_EXPORT False PARENT_SCOPE )
Set ( CPPRTTI_HAS_EXPORT False PARENT_SCOPE )

# Header
If ( CPPRTTI_INSTALL_HEADER )
Set ( CPPRTTI_HAS_EXPORT True PARENT_SCOPE )
Install ( FILES ${CPPRTTI_INCLUDE_DIR}/cpprtti.h
DESTINATION ${CPPRTTI_INSTALL_DIR_INCLUDE} )
Install ( DIRECTORY ${CPPRTTI_INCLUDE_DIR}/cpprtti
DESTINATION ${CPPRTTI_INSTALL_DIR_INCLUDE} )
Install ( TARGETS cpprtti
EXPORT cpprtti
DESTINATION ${CPPRTTI_INSTALL_DIR_INCLUDE} )
EndIf ( )
If ( CPPRTTI_INSTALL_HEADER )
Set ( CPPRTTI_HAS_EXPORT True PARENT_SCOPE )
Install ( FILES ${CPPRTTI_INCLUDE_DIR}/cpprtti.h
DESTINATION ${CPPRTTI_INSTALL_DIR_INCLUDE} )
Install ( DIRECTORY ${CPPRTTI_INCLUDE_DIR}/cpprtti
DESTINATION ${CPPRTTI_INSTALL_DIR_INCLUDE} )
Install ( TARGETS cpprtti
EXPORT cpprtti
DESTINATION ${CPPRTTI_INSTALL_DIR_INCLUDE} )
EndIf ( )

+ 47
- 40
test/CMakeLists.txt View File

@@ -1,52 +1,59 @@
# Initialize ######################################################################################

Include ( cotire OPTIONAL RESULT_VARIABLE HAS_COTIRE )
Include ( pedantic OPTIONAL RESULT_VARIABLE HAS_PEDANTIC )
Include ( cmake_tests OPTIONAL RESULT_VARIABLE HAS_CMAKE_TESTS )
Include ( cotire OPTIONAL RESULT_VARIABLE HAS_COTIRE )
Include ( pedantic OPTIONAL RESULT_VARIABLE HAS_PEDANTIC )
Include ( cmake_tests OPTIONAL RESULT_VARIABLE HAS_CMAKE_TESTS )

Find_Package ( Sanitizers QUIET )

# Test ############################################################################################

Find_Package ( GTest )
If ( NOT "${GTest_FOUND}" )
Return ( )
EndIf ( )
Find_Package ( GTest )
If ( NOT "${GTest_FOUND}" )
Return ( )
EndIf ( )

File ( GLOB_RECURSE CPPRTTI_TEST_HEADER_FILES
${CMAKE_CURRENT_SOURCE_DIR}/*.h )
File ( GLOB_RECURSE CPPRTTI_TEST_INLINE_FILES
${CMAKE_CURRENT_SOURCE_DIR}/*.inl )
File ( GLOB_RECURSE CPPRTTI_TEST_SOURCE_FILES
RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/*.cpp )
File ( GLOB_RECURSE CPPRTTI_TEST_HEADER_FILES
${CMAKE_CURRENT_SOURCE_DIR}/*.h )
File ( GLOB_RECURSE CPPRTTI_TEST_INLINE_FILES
${CMAKE_CURRENT_SOURCE_DIR}/*.inl )
File ( GLOB_RECURSE CPPRTTI_TEST_SOURCE_FILES
RELATIVE ${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_SOURCE_DIR}/*.cpp )

ForEach ( FILE IN LISTS CPPRTTI_TEST_SOURCE_FILES )
ForEach ( FILE IN LISTS CPPRTTI_TEST_SOURCE_FILES )
# add test
Get_Filename_Component ( TEST_DIR ${FILE} DIRECTORY )
Get_Filename_Component ( TEST_NAME ${FILE} NAME_WE )
Set ( TEST_NAME "${TEST_DIR}/${TEST_NAME}" )
String ( REPLACE "\\" "-" TEST_NAME "${TEST_NAME}" )
String ( REPLACE "/" "-" TEST_NAME "${TEST_NAME}" )
String ( REPLACE "_" "-" TEST_NAME "${TEST_NAME}" )
Set ( TEST_NAME "test-${TEST_NAME}" )
Add_Executable ( ${TEST_NAME}
EXCLUDE_FROM_ALL
${CPPRTTI_TEST_HEADER_FILES}
${CPPRTTI_TEST_INLINE_FILES}
${FILE} )
Target_Link_Libraries ( ${TEST_NAME}
PUBLIC
cpprtti
GTest::Main )
Get_Filename_Component ( TEST_DIR ${FILE} DIRECTORY )
Get_Filename_Component ( TEST_NAME ${FILE} NAME_WE )
Set ( TEST_NAME "${TEST_DIR}/${TEST_NAME}" )
String ( REPLACE "\\" "-" TEST_NAME "${TEST_NAME}" )
String ( REPLACE "/" "-" TEST_NAME "${TEST_NAME}" )
String ( REPLACE "_" "-" TEST_NAME "${TEST_NAME}" )
Set ( TEST_NAME "test-${TEST_NAME}" )
Add_Executable ( ${TEST_NAME}
EXCLUDE_FROM_ALL
${CPPRTTI_TEST_HEADER_FILES}
${CPPRTTI_TEST_INLINE_FILES}
${FILE} )
Target_Link_Libraries ( ${TEST_NAME}
PUBLIC
cpprtti
GTest::Main )

# Sanitizers
If ( Sanitizers_FOUND )
Add_Sanitizers ( ${TEST_NAME} )
EndIf ( )

# pedantic
If ( HAS_PEDANTIC )
Pedantic_Apply_Flags_Target ( ${TEST_NAME} ALL )
EndIf ( )
If ( HAS_PEDANTIC )
Pedantic_Apply_Flags_Target ( ${TEST_NAME} ALL )
EndIf ( )

# test
If ( HAS_CMAKE_TESTS )
Add_CMake_Test ( NAME ${TEST_NAME} TARGET ${TEST_NAME} GROUP cpprtti )
Else ( )
Add_Test ( NAME ${TEST_NAME} COMMAND ${TEST_NAME} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} )
EndIf ( )
EndForEach ( )
If ( HAS_CMAKE_TESTS )
Add_CMake_Test ( NAME ${TEST_NAME} TARGET ${TEST_NAME} GROUP cpprtti )
Else ( )
Add_Test ( NAME ${TEST_NAME} COMMAND ${TEST_NAME} WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} )
EndIf ( )
EndForEach ( )

+ 2
- 1
test/cpprtti/misc/variant_tests.cpp View File

@@ -1,5 +1,6 @@
#include <gtest/gtest.h>
#include <cpprtti/misc/variant.h>

#include <cpprtti.h>

using namespace cpprtti;



+ 1
- 0
test/cpprtti/type/class_type_tests.cpp View File

@@ -1,4 +1,5 @@
#include <gtest/gtest.h>

#include <cpprtti.h>

using namespace cpprtti;


Loading…
Cancel
Save