diff --git a/cmake/Custom.cmake b/cmake/Custom.cmake index e0e690f..4e44820 100644 --- a/cmake/Custom.cmake +++ b/cmake/Custom.cmake @@ -44,3 +44,16 @@ function(list_extract OUTPUT REGEX) set(${OUTPUT} ${${OUTPUT}} PARENT_SCOPE) endfunction(list_extract) + + +# Creates an export header similar to generate_export_header, but for templates. +# The main difference is that for MSVC, templates must not get exported. +# When the file ${export_file} is included in source code, the macro ${target_id}_TEMPLATE_API +# may get used to define public visibility for templates on GCC and Clang platforms. +function(generate_template_export_header target target_id export_file) + if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "MSVC") + configure_file(${PROJECT_SOURCE_DIR}/source/codegeneration/template_msvc_api.h.in ${CMAKE_CURRENT_BINARY_DIR}/${export_file}) + else() + configure_file(${PROJECT_SOURCE_DIR}/source/codegeneration/template_api.h.in ${CMAKE_CURRENT_BINARY_DIR}/${export_file}) + endif() +endfunction() diff --git a/source/baselib/CMakeLists.txt b/source/baselib/CMakeLists.txt index 59655cc..806eac2 100644 --- a/source/baselib/CMakeLists.txt +++ b/source/baselib/CMakeLists.txt @@ -19,9 +19,10 @@ message(STATUS "Lib ${target}") # Set API export file and macro string(MAKE_C_IDENTIFIER ${target} target_id) string(TOUPPER ${target_id} target_id) -set(feature_file "include/${target}/${target}_features.h") -set(export_file "include/${target}/${target}_api.h") -set(export_macro "${target_id}_API") +set(feature_file "include/${target}/${target}_features.h") +set(export_file "include/${target}/${target}_export.h") +set(template_export_file "include/${target}/${target}_api.h") +set(export_macro "${target_id}_API") # @@ -90,6 +91,10 @@ generate_export_header(${target} EXPORT_FILE_NAME ${export_file} EXPORT_MACRO_NAME ${export_macro} ) +generate_template_export_header(${target} + ${target_id} + ${template_export_file} +) # diff --git a/source/codegeneration/template_api.h.in b/source/codegeneration/template_api.h.in new file mode 100644 index 0000000..28b7bd2 --- /dev/null +++ b/source/codegeneration/template_api.h.in @@ -0,0 +1,22 @@ + +#ifndef ${target_id}_TEMPLATE_API_H +#define ${target_id}_TEMPLATE_API_H + +#include <${target}/${target}_export.h> + +#ifdef ${target_id}_STATIC_DEFINE +# define ${target_id}_TEMPLATE_API +#else +# ifndef ${target_id}_TEMPLATE_API +# ifdef ${target}_EXPORTS + /* We are building this library */ +# define ${target_id}_TEMPLATE_API __attribute__((visibility("default"))) +# else + /* We are using this library */ +# define ${target_id}_TEMPLATE_API __attribute__((visibility("default"))) +# endif +# endif + +#endif + +#endif diff --git a/source/codegeneration/template_msvc_api.in b/source/codegeneration/template_msvc_api.in new file mode 100644 index 0000000..e9078e9 --- /dev/null +++ b/source/codegeneration/template_msvc_api.in @@ -0,0 +1,22 @@ + +#ifndef ${target_id}_TEMPLATE_API_H +#define ${target_id}_TEMPLATE_API_H + +#include <${target}/${target}_export.h> + +#ifdef ${target_id}_STATIC_DEFINE +# define ${target_id}_TEMPLATE_API +#else +# ifndef ${target_id}_TEMPLATE_API +# ifdef ${target}_EXPORTS + /* We are building this library */ +# define ${target_id}_TEMPLATE_API +# else + /* We are using this library */ +# define ${target_id}_TEMPLATE_API +# endif +# endif + +#endif + +#endif diff --git a/source/examples/fibcmd/main.cpp b/source/examples/fibcmd/main.cpp index b7c50cd..30d9829 100644 --- a/source/examples/fibcmd/main.cpp +++ b/source/examples/fibcmd/main.cpp @@ -3,6 +3,7 @@ #include +#include #include @@ -15,7 +16,8 @@ int main(int /*argc*/, char* /*argv*/[]) // Calculate and print fibonacci number std::cout << "Fibonacci library" << std::endl; std::cout << "========================================" << std::endl; - std::cout << "Fibonacci(8) = " << fiblib::Fibonacci()(8) << std::endl; + std::cout << "CTFibonacci(6) = " << fiblib::CTFibonacci<6>::value << std::endl; + std::cout << "Fibonacci(8) = " << fiblib::Fibonacci()(8) << std::endl; std::cout << std::endl; return 0; diff --git a/source/fiblib/CMakeLists.txt b/source/fiblib/CMakeLists.txt index 8efb3fa..cbc2735 100644 --- a/source/fiblib/CMakeLists.txt +++ b/source/fiblib/CMakeLists.txt @@ -19,9 +19,10 @@ message(STATUS "Lib ${target}") # Set API export file and macro string(MAKE_C_IDENTIFIER ${target} target_id) string(TOUPPER ${target_id} target_id) -set(feature_file "include/${target}/${target}_features.h") -set(export_file "include/${target}/${target}_api.h") -set(export_macro "${target_id}_API") +set(feature_file "include/${target}/${target}_features.h") +set(export_file "include/${target}/${target}_export.h") +set(template_export_file "include/${target}/${target}_api.h") +set(export_macro "${target_id}_API") # @@ -32,6 +33,8 @@ set(include_path "${CMAKE_CURRENT_SOURCE_DIR}/include/${target}") set(source_path "${CMAKE_CURRENT_SOURCE_DIR}/source") set(headers + ${include_path}/CTFibonacci.h + ${include_path}/CTFibonacci.inl ${include_path}/Fibonacci.h ) @@ -90,6 +93,10 @@ generate_export_header(${target} EXPORT_FILE_NAME ${export_file} EXPORT_MACRO_NAME ${export_macro} ) +generate_template_export_header(${target} + ${target_id} + ${template_export_file} +) # diff --git a/source/fiblib/include/fiblib/CTFibonacci.h b/source/fiblib/include/fiblib/CTFibonacci.h new file mode 100644 index 0000000..4b9d2d5 --- /dev/null +++ b/source/fiblib/include/fiblib/CTFibonacci.h @@ -0,0 +1,29 @@ + +#pragma once + + +#include + + +namespace fiblib +{ + + +/** +* @brief +* Compile-time computation of fibonacci numbers +*/ +template +class FIBLIB_TEMPLATE_API CTFibonacci +{ +public: + enum { + value = CTFibonacci::value + CTFibonacci::value + }; +}; + + +} // namespace fiblib + + +#include diff --git a/source/fiblib/include/fiblib/CTFibonacci.inl b/source/fiblib/include/fiblib/CTFibonacci.inl new file mode 100644 index 0000000..900a789 --- /dev/null +++ b/source/fiblib/include/fiblib/CTFibonacci.inl @@ -0,0 +1,28 @@ + +#pragma once + + +namespace fiblib +{ + + +template <> +class FIBLIB_TEMPLATE_API CTFibonacci<0> +{ +public: + enum { + value = 0 + }; +}; + +template <> +class FIBLIB_TEMPLATE_API CTFibonacci<1> +{ +public: + enum { + value = 1 + }; +}; + + +} // namespace fiblib