* Updated project structuremaster
@@ -1,3 +1,3 @@ | |||||
[submodule "cmake/modules"] | [submodule "cmake/modules"] | ||||
path = cmake/modules | path = cmake/modules | ||||
url = https://git.bergmann89.de/cpp/CmakeModules.git | |||||
url = b3rgmann@git.bergmann89.de:cpp/CMakeModules.git |
@@ -1,63 +1,63 @@ | |||||
# Initialize CMake ################################################################################ | # Initialize CMake ################################################################################ | ||||
CMake_Minimum_Required ( VERSION 3.12.0 FATAL_ERROR ) | |||||
CMake_Minimum_Required ( VERSION 3.12.0 FATAL_ERROR ) | |||||
# Set CMAKE_BUILD_TYPE | # 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 | # 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 ######################################################################################### | # 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 | # 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 | # 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.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 ) |
@@ -0,0 +1,3 @@ | |||||
# cpprtti | |||||
C++ run time type information library. |
@@ -25,7 +25,7 @@ If ( NOT ${CHECKOUT_RET} EQUAL 0 ) | |||||
EndIf ( ) | EndIf ( ) | ||||
# Include Cloned Repository | # 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} ) | FindLocalModule ( cppcore ${CPPCORE_CHECKOUT_DIR} ) | ||||
# Create Alias Targets | # Create Alias Targets | ||||
@@ -25,7 +25,7 @@ If ( NOT ${CHECKOUT_RET} EQUAL 0 ) | |||||
EndIf ( ) | EndIf ( ) | ||||
# Include Cloned Repository | # 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} ) | FindLocalModule ( cppmp ${CPPMP_CHECKOUT_DIR} ) | ||||
# Create Alias Targets | # Create Alias Targets | ||||
@@ -1,28 +1,28 @@ | |||||
# This file contains constant variables that are fixed to this project | # This file contains constant variables that are fixed to this project | ||||
# Version | # 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 | # 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 generated variables for further usage | ||||
Include ( ${CMAKE_CURRENT_LIST_DIR}/cpprtti-var.cmake ) | |||||
Include ( ${CMAKE_CURRENT_LIST_DIR}/cpprtti-var.cmake ) | |||||
# Install directories | # 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 | # 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 ) |
@@ -1,23 +1,11 @@ | |||||
# This file contains options that can be passed to the cmake command | # 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 ) |
@@ -1,26 +1,32 @@ | |||||
# This file contains generated variables that are needed for the project | # This file contains generated variables that are needed for the project | ||||
# Git Version | # 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 | # 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 @@ | |||||
Subproject commit ebbae4fbb42d671331b4c6e9d1d142f41dcacc1b | |||||
Subproject commit 94b9877d65e46c9d8169ebc46f163d02e4d9dcf3 |
@@ -4,3 +4,5 @@ | |||||
#include <cpprtti/registry.h> | #include <cpprtti/registry.h> | ||||
#include <cpprtti/traits.h> | #include <cpprtti/traits.h> | ||||
#include <cpprtti/types.h> | #include <cpprtti/types.h> | ||||
#include <cpprtti/registry.inl> |
@@ -2,8 +2,10 @@ | |||||
#include "misc/exception.h" | #include "misc/exception.h" | ||||
#include "misc/helper.h" | #include "misc/helper.h" | ||||
#include "misc/storage.h" | |||||
#include "misc/variant.h" | #include "misc/variant.h" | ||||
#include "misc/exception.inl" | #include "misc/exception.inl" | ||||
#include "misc/helper.inl" | #include "misc/helper.inl" | ||||
#include "misc/storage.inl" | |||||
#include "misc/variant.inl" | #include "misc/variant.inl" |
@@ -23,11 +23,15 @@ namespace cpprtti | |||||
/* variant */ | /* variant */ | ||||
variant_error = 2000, | variant_error = 2000, | ||||
variant_is_empty, //!< The variant does not store any value! | 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_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_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 */ | ||||
class_error = 3000, | 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_member_already_exists, //!< Unable to create member: Name is already in use! | ||||
class_type_mismatch, //!< Type does not match the. | class_type_mismatch, //!< Type does not match the. | ||||
class_member_not_readable, //!< Member variable is not readable! | class_member_not_readable, //!< Member variable is not readable! | ||||
@@ -72,5 +76,3 @@ namespace cpprtti | |||||
}; | }; | ||||
} | } | ||||
#include "exception.inl" |
@@ -7,6 +7,13 @@ namespace cpprtti | |||||
{ | { | ||||
using type_id = size_t; | 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. | * @brief Get the ID of a certain C++ type. | ||||
@@ -21,5 +28,3 @@ namespace cpprtti | |||||
inline const std::string& get_type_name(); | inline const std::string& get_type_name(); | ||||
} | } | ||||
#include "helper.inl" |
@@ -10,7 +10,11 @@ namespace cpprtti | |||||
namespace __impl | 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 { }; | static type_id value { }; | ||||
return ++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> | template<typename X> | ||||
type_id get_type_id() | 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; | return value; | ||||
} | } | ||||
@@ -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; | |||||
}; | |||||
} |
@@ -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; | |||||
} | |||||
} |
@@ -5,11 +5,13 @@ | |||||
#include <cppmp/misc/generic_predicate.h> | #include <cppmp/misc/generic_predicate.h> | ||||
#include "helper.h" | #include "helper.h" | ||||
#include "../types/type.h" | |||||
namespace cpprtti | namespace cpprtti | ||||
{ | { | ||||
struct type; | |||||
struct variant; | |||||
namespace __impl | namespace __impl | ||||
{ | { | ||||
@@ -22,18 +24,36 @@ namespace cpprtti | |||||
struct variant_impl | struct variant_impl | ||||
{ | { | ||||
public: | |||||
const type& type; | const type& type; | ||||
void * data { nullptr }; | void * data { nullptr }; | ||||
bool is_const { false }; | bool is_const { false }; | ||||
bool is_reference { false }; | bool is_reference { false }; | ||||
public: | |||||
/** | /** | ||||
* @brief Constructor. | * @brief Constructor. | ||||
*/ | */ | ||||
inline variant_impl(const cpprtti::type& p_type); | 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. | * @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. | * @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> { }; | constexpr decltype(auto) make_variant = cppmp::generic_predicate<__impl::variant_builder> { }; | ||||
} | } | ||||
#include "variant.inl" |
@@ -2,6 +2,7 @@ | |||||
#include <cppcore/misc/string_builder.h> | #include <cppcore/misc/string_builder.h> | ||||
#include <cppmp/core/types.h> | |||||
#include <cppmp/core/checker.h> | #include <cppmp/core/checker.h> | ||||
#include <cppmp/core/modifier.h> | #include <cppmp/core/modifier.h> | ||||
#include <cppmp/core/conditionals.h> | #include <cppmp/core/conditionals.h> | ||||
@@ -24,6 +25,44 @@ namespace cpprtti | |||||
: type(p_type) | : 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 */ | /* variant_builder - default */ | ||||
template<typename X, typename> | template<typename X, typename> | ||||
@@ -61,6 +100,11 @@ namespace cpprtti | |||||
is_const = cppmp::is_const_v<cppmp::remove_reference_t<T>>; | is_const = cppmp::is_const_v<cppmp::remove_reference_t<T>>; | ||||
is_reference = false; | 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> | template<typename X_registry, typename X> | ||||
@@ -94,6 +138,30 @@ namespace cpprtti | |||||
is_const = cppmp::is_const_v<cppmp::remove_reference_t<T>>; | is_const = cppmp::is_const_v<cppmp::remove_reference_t<T>>; | ||||
is_reference = true; | 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> | template<typename X_registry, typename X> | ||||
@@ -121,6 +189,19 @@ namespace cpprtti | |||||
{ return std::forward<X>(x); } | { 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 */ | /* value_extractor - default */ | ||||
template<typename X, typename = void> | 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); } | { 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 | variant::operator bool() const | ||||
{ return static_cast<bool>(_impl); } | { return static_cast<bool>(_impl); } | ||||
@@ -4,6 +4,7 @@ | |||||
#include <memory> | #include <memory> | ||||
#include "types/type.h" | #include "types/type.h" | ||||
#include "types/type_decorator.h" | |||||
namespace cpprtti | namespace cpprtti | ||||
{ | { | ||||
@@ -88,9 +89,7 @@ namespace cpprtti | |||||
* @brief Create a new type for the passed C++ type with the passed implementation type. | * @brief Create a new type for the passed C++ type with the passed implementation type. | ||||
*/ | */ | ||||
template<typename T_impl> | template<typename T_impl> | ||||
inline T_impl& create(); | |||||
inline type_decorator<T_impl>& create(); | |||||
}; | }; | ||||
} | } | ||||
#include "registry.inl" |
@@ -18,7 +18,8 @@ namespace cpprtti | |||||
template<typename T_type> | template<typename T_type> | ||||
const auto& registry::get() const | 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>(); | auto * t = find<T_type>(); | ||||
@@ -31,7 +32,7 @@ namespace cpprtti | |||||
<< get_type_name<T_type>()); | << get_type_name<T_type>()); | ||||
} | } | ||||
auto * ret = dynamic_cast<const impl_type *>(t); | |||||
auto * ret = dynamic_cast<const decorated_type *>(t); | |||||
if (!ret) | if (!ret) | ||||
{ | { | ||||
throw exception( | throw exception( | ||||
@@ -47,11 +48,14 @@ namespace cpprtti | |||||
template<typename T_type, typename T_impl> | template<typename T_type, typename T_impl> | ||||
auto& registry::get() | auto& registry::get() | ||||
{ | { | ||||
using impl_type = T_impl; | |||||
using decorated_type = type_decorator<impl_type>; | |||||
auto * t = find<T_type>(); | auto * t = find<T_type>(); | ||||
if (!t) | 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) | if (!ret) | ||||
{ | { | ||||
throw exception( | throw exception( | ||||
@@ -105,9 +109,11 @@ namespace cpprtti | |||||
} | } | ||||
template<typename T_impl> | 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()); | auto id_it = _id_map.find(impl->id()); | ||||
if (id_it != _id_map.end()) | if (id_it != _id_map.end()) | ||||
@@ -10,5 +10,3 @@ namespace cpprtti | |||||
using default_type_t = typename default_type_trait<cppmp::decay_t<T>>::type; | using default_type_t = typename default_type_trait<cppmp::decay_t<T>>::type; | ||||
} | } | ||||
#include "default_type.inl" |
@@ -5,10 +5,12 @@ | |||||
#include "types/fundamental_type_tpl.h" | #include "types/fundamental_type_tpl.h" | ||||
#include "types/fundamental_type.h" | #include "types/fundamental_type.h" | ||||
#include "types/member.h" | #include "types/member.h" | ||||
#include "types/type_decorator.h" | |||||
#include "types/type.h" | #include "types/type.h" | ||||
#include "types/class_type_tpl.inl" | #include "types/class_type_tpl.inl" | ||||
#include "types/class_type.inl" | #include "types/class_type.inl" | ||||
#include "types/fundamental_type_tpl.inl" | #include "types/fundamental_type_tpl.inl" | ||||
#include "types/fundamental_type.inl" | #include "types/fundamental_type.inl" | ||||
#include "types/type_decorator.inl" | |||||
#include "types/type.inl" | #include "types/type.inl" |
@@ -31,13 +31,18 @@ namespace cpprtti | |||||
/** | /** | ||||
* @brief Get a map of all registered members. | * @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. | * @brief Register a new member variable. | ||||
*/ | */ | ||||
template<typename... T_args> | template<typename... T_args> | ||||
auto& add_member_variable( | |||||
inline auto& add_member_variable( | |||||
const std::string& p_name, | const std::string& p_name, | ||||
T_args&&... p_args); | T_args&&... p_args); | ||||
@@ -45,11 +50,9 @@ namespace cpprtti | |||||
* @brief Register a new member method. | * @brief Register a new member method. | ||||
*/ | */ | ||||
template<typename... T_args> | template<typename... T_args> | ||||
auto& add_member_method( | |||||
inline auto& add_member_method( | |||||
const std::string& p_name, | const std::string& p_name, | ||||
T_args&&... p_args); | T_args&&... p_args); | ||||
}; | }; | ||||
} | } | ||||
#include "class_type.inl" |
@@ -16,6 +16,22 @@ namespace cpprtti | |||||
: type(p_registry, p_id, p_name, rtti_type_t::class_type) | : 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 | const class_type::member_map& class_type | ||||
::members() const | ::members() const | ||||
{ return _members; } | { return _members; } | ||||
@@ -21,5 +21,3 @@ namespace cpprtti | |||||
}; | }; | ||||
} | } | ||||
#include "class_type_tpl.inl" |
@@ -19,5 +19,3 @@ namespace cpprtti | |||||
}; | }; | ||||
} | } | ||||
#include "fundamental_type.inl" |
@@ -21,5 +21,3 @@ namespace cpprtti | |||||
}; | }; | ||||
} | } | ||||
#include "fundamental_type_tpl.inl" |
@@ -3,6 +3,7 @@ | |||||
#include <string> | #include <string> | ||||
#include "../../types/type.h" | #include "../../types/type.h" | ||||
#include "../../misc/storage.h" | |||||
namespace cpprtti | namespace cpprtti | ||||
{ | { | ||||
@@ -15,6 +16,7 @@ namespace cpprtti | |||||
}; | }; | ||||
struct member | struct member | ||||
: public storage_container | |||||
{ | { | ||||
protected: | protected: | ||||
cpprtti::type& _owner; | cpprtti::type& _owner; | ||||
@@ -52,5 +54,3 @@ namespace cpprtti | |||||
}; | }; | ||||
} | } | ||||
#include "member.inl" |
@@ -3,6 +3,7 @@ | |||||
#include <cppmp/misc/generic_predicate.h> | #include <cppmp/misc/generic_predicate.h> | ||||
#include "member.h" | #include "member.h" | ||||
#include "../../misc/variant.h" | |||||
namespace cpprtti | namespace cpprtti | ||||
{ | { | ||||
@@ -42,5 +43,3 @@ namespace cpprtti | |||||
constexpr decltype(auto) make_member_method = cppmp::generic_predicate<__impl::member_method_builder> { }; | constexpr decltype(auto) make_member_method = cppmp::generic_predicate<__impl::member_method_builder> { }; | ||||
} | } | ||||
#include "member_method.inl" |
@@ -3,6 +3,7 @@ | |||||
#include <cppmp/traits/lambda_traits.h> | #include <cppmp/traits/lambda_traits.h> | ||||
#include "member_method.h" | #include "member_method.h" | ||||
#include "../../misc/variant.h" | |||||
namespace cpprtti | namespace cpprtti | ||||
{ | { | ||||
@@ -36,17 +36,17 @@ namespace cpprtti | |||||
/** | /** | ||||
* @brief RTTI type of that member represents. | * @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. | * @brief Check if the variable is readable. | ||||
*/ | */ | ||||
bool is_readale() const; | |||||
inline bool is_readale() const; | |||||
/** | /** | ||||
* @brief Check if the variable is writable. | * @brief Check if the variable is writable. | ||||
*/ | */ | ||||
bool is_writable() const; | |||||
inline bool is_writable() const; | |||||
/** | /** | ||||
* @brief Get the current value of the member. | * @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> { }; | constexpr decltype(auto) make_member_variable = cppmp::generic_predicate<__impl::member_variable_builder> { }; | ||||
} | } | ||||
#include "member_variable.inl" |
@@ -86,7 +86,8 @@ namespace cpprtti | |||||
static constexpr decltype(auto) is_read_only_v = | 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<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 */ | /* setter_info_trait */ | ||||
@@ -1,8 +1,12 @@ | |||||
#pragma once | #pragma once | ||||
#include <map> | |||||
#include <string> | #include <string> | ||||
#include <functional> | |||||
#include <cpprtti/misc/helper.h> | #include <cpprtti/misc/helper.h> | ||||
#include <cpprtti/misc/variant.h> | |||||
#include <cpprtti/misc/storage.h> | |||||
namespace cpprtti | namespace cpprtti | ||||
{ | { | ||||
@@ -22,12 +26,21 @@ namespace cpprtti | |||||
* @brief represents any C++ type | * @brief represents any C++ type | ||||
*/ | */ | ||||
struct 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: | protected: | ||||
cpprtti::registry& _registry; //!< Type registry this type belongs to. | cpprtti::registry& _registry; //!< Type registry this type belongs to. | ||||
type_id _id; //!< Unique ID | type_id _id; //!< Unique ID | ||||
std::string _name; //!< Name of the type. | 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: | public: | ||||
/** | /** | ||||
@@ -68,8 +81,28 @@ namespace cpprtti | |||||
* @brief Get the RTTI type of this type object. | * @brief Get the RTTI type of this type object. | ||||
*/ | */ | ||||
inline rtti_type_t rtti_type() const; | 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" |
@@ -1,6 +1,7 @@ | |||||
#pragma once | #pragma once | ||||
#include "type.h" | #include "type.h" | ||||
#include "../registry.h" | |||||
namespace cpprtti | namespace cpprtti | ||||
{ | { | ||||
@@ -33,4 +34,38 @@ namespace cpprtti | |||||
rtti_type_t type::rtti_type() const | rtti_type_t type::rtti_type() const | ||||
{ return _rtti_type; } | { 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; | |||||
} | |||||
} | } |
@@ -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); | |||||
}; | |||||
} |
@@ -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; | |||||
} | |||||
} |
@@ -1,38 +1,37 @@ | |||||
# Initialize ###################################################################################### | # 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 ######################################################################################### | # Install ######################################################################################### | ||||
Set ( CPPRTTI_HAS_EXPORT False PARENT_SCOPE ) | |||||
Set ( CPPRTTI_HAS_EXPORT False PARENT_SCOPE ) | |||||
# Header | # 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 ( ) |
@@ -1,52 +1,59 @@ | |||||
# Initialize ###################################################################################### | # 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 ############################################################################################ | # 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 | # 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 | # pedantic | ||||
If ( HAS_PEDANTIC ) | |||||
Pedantic_Apply_Flags_Target ( ${TEST_NAME} ALL ) | |||||
EndIf ( ) | |||||
If ( HAS_PEDANTIC ) | |||||
Pedantic_Apply_Flags_Target ( ${TEST_NAME} ALL ) | |||||
EndIf ( ) | |||||
# test | # 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 ( ) |
@@ -1,5 +1,6 @@ | |||||
#include <gtest/gtest.h> | #include <gtest/gtest.h> | ||||
#include <cpprtti/misc/variant.h> | |||||
#include <cpprtti.h> | |||||
using namespace cpprtti; | using namespace cpprtti; | ||||
@@ -1,4 +1,5 @@ | |||||
#include <gtest/gtest.h> | #include <gtest/gtest.h> | ||||
#include <cpprtti.h> | #include <cpprtti.h> | ||||
using namespace cpprtti; | using namespace cpprtti; | ||||