* Updated project structuremaster
@@ -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 |
@@ -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 ) |
@@ -0,0 +1,3 @@ | |||
# cpprtti | |||
C++ run time type information library. |
@@ -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 | |||
@@ -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 | |||
@@ -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 ) |
@@ -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 ) |
@@ -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 @@ | |||
Subproject commit ebbae4fbb42d671331b4c6e9d1d142f41dcacc1b | |||
Subproject commit 94b9877d65e46c9d8169ebc46f163d02e4d9dcf3 |
@@ -4,3 +4,5 @@ | |||
#include <cpprtti/registry.h> | |||
#include <cpprtti/traits.h> | |||
#include <cpprtti/types.h> | |||
#include <cpprtti/registry.inl> |
@@ -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" |
@@ -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,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" |
@@ -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; | |||
} | |||
@@ -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 "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" |
@@ -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); } | |||
@@ -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" |
@@ -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()) | |||
@@ -10,5 +10,3 @@ namespace cpprtti | |||
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.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" |
@@ -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,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; } | |||
@@ -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 "../../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" |
@@ -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" |
@@ -3,6 +3,7 @@ | |||
#include <cppmp/traits/lambda_traits.h> | |||
#include "member_method.h" | |||
#include "../../misc/variant.h" | |||
namespace cpprtti | |||
{ | |||
@@ -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" |
@@ -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 */ | |||
@@ -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" |
@@ -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; | |||
} | |||
} |
@@ -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 ###################################################################################### | |||
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 ( ) |
@@ -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 ( ) |
@@ -1,5 +1,6 @@ | |||
#include <gtest/gtest.h> | |||
#include <cpprtti/misc/variant.h> | |||
#include <cpprtti.h> | |||
using namespace cpprtti; | |||
@@ -1,4 +1,5 @@ | |||
#include <gtest/gtest.h> | |||
#include <cpprtti.h> | |||
using namespace cpprtti; | |||