Implements c++ reflection check

This commit is contained in:
2025-11-15 23:29:49 -05:00
parent 2adae5a893
commit fdfc8b62ec
8 changed files with 88 additions and 15 deletions

View File

@@ -1,5 +1,5 @@
include(compiler/features)
include(helpers)
include(git/commit)
@@ -23,8 +23,4 @@ elseif (UNIX)
include(os/linux)
else ()
message(DEBUG "Unknown Platform")
endif ()
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/dependencies" ${CMAKE_MODULE_PATH})
message(DEBUG "Leaving ${CMAKE_CURRENT_LIST_FILE}")
endif ()

View File

@@ -0,0 +1 @@
include(features/reflection)

View File

@@ -7,15 +7,15 @@
function(SetFGLFlags TARGET)
GET_PROPERTY(FGL_COMPILE_FLAGS GLOBAL PROPERTY FGL_COMPILE_FLAGS)
GET_PROPERTY(FGL_LINKS_FLAGS GLOBAL PROPERTY FGL_LINK_FLAGS)
target_compile_options(${TARGET} PUBLIC ${FGL_COMPILE_FLAGS})
target_compile_options(${TARGET} PRIVATE ${FGL_COMPILE_FLAGS})
message("Set target ${TARGET} to use flags\n${FGL_COMPILE_FLAGS}")
target_link_options(${TARGET} PUBLIC ${FGL_LINK_FLAGS})
target_link_options(${TARGET} PRIVATE ${FGL_LINK_FLAGS})
endfunction()
function(SetDependencyFlags TARGET)
GET_PROPERTY(FGL_CHILD_FLAGS GLOBAL PROPERTY FGL_CHILD_FLAGS)
GET_PROPERTY(FGL_LINKS_FLAGS GLOBAL PROPERTY FGL_LINK_FLAGS)
target_compile_options(${TARGET} PUBLIC ${FGL_CHILD_FLAGS})
target_compile_options(${TARGET} PRIVATE ${FGL_CHILD_FLAGS})
message("Set dependency ${TARGET} to use flags\n${FGL_CHILD_FLAGS}")
target_link_options(${TARGET} PUBLIC ${FGL_LINK_FLAGS})
target_link_options(${TARGET} PRIVATE ${FGL_LINK_FLAGS})
endfunction()

View File

@@ -136,7 +136,10 @@
list(APPEND FGL_CONFIG "-ftree-vectorize")
list(APPEND FGL_CONFIG "-fmax-errors=2")
list(APPEND FGL_CONFIG "-std=c++23")
if (HAS_CPP_REFLECTION)
list(APPEND FGL_CONFIG "-freflection")
endif ()
list(APPEND FGL_CONFIG "-fdata-sections")
list(APPEND FGL_CONFIG "-ffunction-sections")
@@ -183,8 +186,10 @@
set(FGL_LINK_FLAGS "-Wl,--gcc-sections;-Wl,--print-gc-sections" PARENT_SCOPE)
SET_PROPERTY(GLOBAL PROPERTY FGL_FLAGS ${FGL_FLAGS})
SET_PROPERTY(GLOBAL PROPERTY FGL_CHILD_FLAGS ${FGL_CHILD_FLAGS})
set_property(GLOBAL PROPERTY FGL_COMPILE_FLAGS ${FGL_FLAGS})
set_property(GLOBAL PROPERTY FGL_LINK_FLAGS ${FGL_LINK_FLAGS})
set_property(GLOBAL PROPERTY FGL_CHILD_FLAGS ${FGL_CHILD_FLAGS})
message("-- FGL_FLAGS: ${FGL_FLAGS}")
message("-- FGL_CHILD_FLAGS: ${FGL_CHILD_FLAGS}")

View File

@@ -0,0 +1,14 @@
set(REFLECTION_SRC "${CMAKE_CURRENT_LIST_DIR}/reflection.cpp")
try_compile(HAS_CPP_REFLECTION
${CMAKE_BINARY_DIR} # build directory
${REFLECTION_SRC} # source file
CMAKE_FLAGS "-DCMAKE_CXX_STANDARD=26"
COMPILE_DEFINITIONS "-freflection"
)
if (HAS_CPP_REFLECTION)
message(STATUS "Compiler supports C++ reflection")
else ()
message(STATUS "Compiler does NOT support C++ reflection")
endif ()

View File

@@ -0,0 +1,57 @@
#include <meta>
using namespace std::meta;
template < typename E, bool B = is_enumerable_type( ^^E ) >
constexpr std::string_view enum_to_string( E e )
{
if constexpr ( B )
{
constexpr info Enums = reflect_constant_array( enumerators_of( ^^E ) );
template for ( constexpr info I : [:Enums:] ) if ( e == [:I:] ) return identifier_of( I );
}
return "<unnamed>";
}
template < typename E, bool B = is_enumerable_type( ^^E ) >
constexpr std::optional< E > string_to_enum( std::string_view s )
{
if constexpr ( B )
{
constexpr info Enums = reflect_constant_array( enumerators_of( ^^E ) );
template for ( constexpr info I : [:Enums:] ) if ( s == identifier_of( I ) ) return [:I:];
}
return std::nullopt;
}
consteval void test()
{
enum class Color : int;
static_assert( enum_to_string( Color { 0 } ) == "<unnamed>" );
static_assert( enum_to_string( Color { 3 } ) == "<unnamed>" );
enum class Color : int
{
Red,
Green,
Blue,
Yellow
};
static_assert( enum_to_string( Color::Red ) == "Red" );
static_assert( enum_to_string( Color::Green ) == "Green" );
static_assert( enum_to_string( Color::Blue ) == "Blue" );
static_assert( enum_to_string( Color::Yellow ) == "Yellow" );
static_assert( enum_to_string( Color { 0 } ) == "Red" );
static_assert( enum_to_string( Color { 3 } ) == "Yellow" );
static_assert( enum_to_string( Color { 4 } ) == "<unnamed>" );
static_assert( string_to_enum< Color >( "Red" ) == Color::Red );
static_assert( string_to_enum< Color >( "Green" ) == Color::Green );
static_assert( string_to_enum< Color >( "Blue" ) == Color::Blue );
static_assert( string_to_enum< Color >( "Yellow" ) == Color::Yellow );
static_assert( string_to_enum< Color >( "White" ) == std::nullopt );
}
int main()
{
test();
}

View File

@@ -37,7 +37,7 @@ endfunction()
function(setGitTagVersionDefines TARGET)
getGitTagVersion()
message("Adding targets to ${TARGET}_X_VERSION")
message("Adding version info to ${TARGET}")
target_compile_definitions(${TARGET} PUBLIC
${TARGET}_MAJOR_VERSION=${VERSION_MAJOR}

View File

@@ -23,7 +23,7 @@ function(ConfigureFGLTarget NAME SRC_DIR INCLUDE_DIR)
target_compile_definitions(${NAME} PUBLIC "-DFGL_STRICT_WARNINGS=1")
endif ()
target_compile_features(${NAME} PUBLIC cxx_std_23)
target_compile_features(${NAME} PUBLIC cxx_std_26)
endfunction()
function(SplitDebugSymbols NAME)