diff options
| author | Felix Morgner <felix.morgner@gmail.com> | 2019-12-22 19:47:21 +0100 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@gmail.com> | 2019-12-22 21:12:58 +0100 |
| commit | 6370b3fc6ffb973cc272f18d18db521c02fea0f1 (patch) | |
| tree | da965d0a1bb37d523d5e840d74f9a07676a818a0 | |
| download | newtype-6370b3fc6ffb973cc272f18d18db521c02fea0f1.tar.xz newtype-6370b3fc6ffb973cc272f18d18db521c02fea0f1.zip | |
newtype: initial commit
| -rw-r--r-- | .clang-format | 111 | ||||
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | .vscode/c_cpp_properties.json | 16 | ||||
| -rw-r--r-- | .vscode/settings.json | 72 | ||||
| -rw-r--r-- | CMakeLists.txt | 145 | ||||
| -rw-r--r-- | LICENSE | 26 | ||||
| -rw-r--r-- | cmake/Modules/Conan.cmake | 554 | ||||
| -rw-r--r-- | cmake/Modules/DiscoverTests.cmake | 55 | ||||
| -rw-r--r-- | cmake/Modules/DiscoverTestsImpl.cmake | 39 | ||||
| -rw-r--r-- | cmake/config.cmake.in | 4 | ||||
| -rw-r--r-- | conanfile.py | 33 | ||||
| -rw-r--r-- | doc/Pipfile | 14 | ||||
| -rw-r--r-- | doc/Pipfile.lock | 232 | ||||
| -rw-r--r-- | doc/src/conf.py | 44 | ||||
| -rw-r--r-- | doc/src/index.rst | 154 | ||||
| -rw-r--r-- | include/newtype/derivable.hpp | 63 | ||||
| -rw-r--r-- | include/newtype/deriving.hpp | 123 | ||||
| -rw-r--r-- | include/newtype/new_type.hpp | 124 | ||||
| -rw-r--r-- | include/newtype/type.hpp | 29 | ||||
| -rw-r--r-- | test/include/derivation_clause_suite.hpp | 11 | ||||
| -rw-r--r-- | test/include/kawaii.hpp | 142 | ||||
| -rw-r--r-- | test/include/new_type_constructor_suite.hpp | 11 | ||||
| -rw-r--r-- | test/src/derivation_clause_suite.cpp | 312 | ||||
| -rw-r--r-- | test/src/driver.cpp | 89 | ||||
| -rw-r--r-- | test/src/new_type_constructor_suite.cpp | 68 |
25 files changed, 2472 insertions, 0 deletions
diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..e834805 --- /dev/null +++ b/.clang-format @@ -0,0 +1,111 @@ +--- +Language: Cpp + +AccessModifierOffset: -2 + +AlignAfterOpenBracket: Align +AlignConsecutiveAssignments: false +AlignConsecutiveDeclarations: false +AlignEscapedNewlines: Right +AlignOperands: true +AlignTrailingComments: true + +AllowAllParametersOfDeclarationOnNextLine: false +AllowAllArgumentsOnNextLine: false +AllowShortBlocksOnASingleLine: false +AllowShortCaseLabelsOnASingleLine: false +AllowShortFunctionsOnASingleLine: None +AllowShortIfStatementsOnASingleLine: false +AllowShortLambdasOnASingleLine: Inline +AllowShortLoopsOnASingleLine: false + +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AlwaysBreakTemplateDeclarations: true + +BinPackArguments: false +BinPackParameters: false + +BraceWrapping: + AfterClass: true + AfterControlStatement: true + AfterEnum: true + AfterFunction: true + AfterNamespace: true + AfterStruct: true + AfterUnion: true + AfterExternBlock: true + BeforeCatch: true + BeforeElse: true + IndentBraces: false + +BreakBeforeBraces: Custom +BreakBeforeInheritanceComma: true +BreakConstructorInitializers: BeforeComma +BreakStringLiterals: true + +ColumnLimit: 144 + +CompactNamespaces: false + +Cpp11BracedListStyle: true + +DerivePointerAlignment: false + +FixNamespaceComments: true + +IncludeBlocks: Regroup +IncludeCategories: + # CUTE Headers + - Regex: '<cute/[[:alnum:]._]+\.(h|hpp)>' + Priority: 200 + # STL Headers + - Regex: '<[[:alnum:]._]+(?!\.(h|hpp))>' + Priority: 400 + # General System Headers + - Regex: '<([[:alnum:]._]/*)+\.(h|hpp)>' + Priority: 300 + # newtype Headers + - Regex: '"newtype/.+\.hpp"' + Priority: 100 + # Local Headers + - Regex: '".+\.hpp"' + Priority: 100 + + +IndentCaseLabels: false +IndentPPDirectives: None +IndentWidth: 2 + +KeepEmptyLinesAtTheStartOfBlocks: true + +MaxEmptyLinesToKeep: 1 + +NamespaceIndentation: All + +PointerAlignment: Middle + +ReflowComments: true + +SortIncludes: true +SortUsingDeclarations: true + +SpaceAfterCStyleCast: false +SpaceAfterTemplateKeyword: false +SpaceBeforeAssignmentOperators: true +SpaceBeforeParens: ControlStatements +SpaceInEmptyParentheses: false +SpacesBeforeTrailingComments: 2 +SpacesInAngles: false +SpacesInContainerLiterals: false +SpacesInCStyleCastParentheses: false +SpacesInParentheses: false +SpacesInSquareBrackets: false + +Standard: Cpp11 + +TabWidth: 2 + +UseTab: Never + +... diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/build
\ No newline at end of file diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..179e475 --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,16 @@ +{ + "configurations": [ + { + "name": "Linux", + "includePath": [ + "${workspaceFolder}/**" + ], + "defines": [], + "compilerPath": "/usr/bin/clang", + "cppStandard": "c++20", + "intelliSenseMode": "clang-x64", + "configurationProvider": "go2sh.cmake-integration" + } + ], + "version": 4 +}
\ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..fd771a0 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,72 @@ +{ + "files.associations": { + ".clang-format": "yaml", + "array": "cpp", + "chrono": "cpp", + "functional": "cpp", + "istream": "cpp", + "ostream": "cpp", + "ratio": "cpp", + "tuple": "cpp", + "type_traits": "cpp", + "utility": "cpp", + "variant": "cpp", + "atomic": "cpp", + "hash_map": "cpp", + "bit": "cpp", + "*.tcc": "cpp", + "cctype": "cpp", + "clocale": "cpp", + "cmath": "cpp", + "condition_variable": "cpp", + "cstdarg": "cpp", + "cstddef": "cpp", + "cstdint": "cpp", + "cstdio": "cpp", + "cstdlib": "cpp", + "cstring": "cpp", + "ctime": "cpp", + "cwchar": "cpp", + "cwctype": "cpp", + "deque": "cpp", + "list": "cpp", + "map": "cpp", + "set": "cpp", + "unordered_map": "cpp", + "vector": "cpp", + "exception": "cpp", + "algorithm": "cpp", + "iterator": "cpp", + "memory": "cpp", + "memory_resource": "cpp", + "numeric": "cpp", + "optional": "cpp", + "random": "cpp", + "string": "cpp", + "string_view": "cpp", + "system_error": "cpp", + "fstream": "cpp", + "initializer_list": "cpp", + "iomanip": "cpp", + "iosfwd": "cpp", + "iostream": "cpp", + "limits": "cpp", + "mutex": "cpp", + "new": "cpp", + "sstream": "cpp", + "stdexcept": "cpp", + "streambuf": "cpp", + "thread": "cpp", + "cfenv": "cpp", + "cinttypes": "cpp", + "typeinfo": "cpp", + "valarray": "cpp" + }, + "cmake.configureArguments": "-DCMAKE_EXPORT_COMPILE_COMMANDS=YES", + "cmake.cpptools.intelliSenseMode": "gcc-x64", + "cmake.cpptools.guessSourceFileConfigurations": true, + "[cpp]": { + "editor.formatOnSave": true + }, + "restructuredtext.confPath": "${workspaceFolder}/doc/src" +}
\ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..845903b --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,145 @@ +cmake_minimum_required(VERSION "3.9.0") + +project("newtype" + VERSION "0.0.1" + LANGUAGES CXX + DESCRIPTION "A library to create new types based on existing ones." +) + +set(CMAKE_CXX_STANDARD "20") +set(CMAKE_CXX_STANDARD_REQUIRED YES) +set(CMAKE_CXX_EXTENSIONS OFF) + +include("CTest") +include("CMakePackageConfigHelpers") + +# 'newtype' library + +add_library("${PROJECT_NAME}" INTERFACE) + +target_include_directories("${PROJECT_NAME}" INTERFACE + $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include> + $<INSTALL_INTERFACE:include> +) + +install(TARGETS "${PROJECT_NAME}" + EXPORT "${PROJECT_NAME}Targets" + PUBLIC_HEADER DESTINATION "include" +) + +install(DIRECTORY "${PROJECT_SOURCE_DIR}/include/" + DESTINATION "include" +) + +# 'newtype' tests + +if(BUILD_TESTING) + include("${PROJECT_SOURCE_DIR}/cmake/Modules/DiscoverTests.cmake") + include("${PROJECT_SOURCE_DIR}/cmake/Modules/Conan.cmake") + + conan_check(REQUIRED) + conan_add_remote(NAME "fmorgner-public" URL "https://api.bintray.com/conan/fmorgner/conan-public") + conan_cmake_run(CONANFILE "conanfile.py" + BASIC_SETUP + CMAKE_TARGETS + BUILD "missing" + NO_OUTPUT_DIRS + ) + + add_executable("${PROJECT_NAME}_tests" + "${PROJECT_SOURCE_DIR}/test/src/driver.cpp" + + "${PROJECT_SOURCE_DIR}/test/src/derivation_clause_suite.cpp" + "${PROJECT_SOURCE_DIR}/test/src/new_type_constructor_suite.cpp" + ) + + target_include_directories("${PROJECT_NAME}_tests" PRIVATE + "${PROJECT_SOURCE_DIR}/test/include" + ) + + target_link_libraries("${PROJECT_NAME}_tests" + "newtype" + "CONAN_PKG::CUTE" + "CONAN_PKG::lyra" + ) + + target_compile_options("${PROJECT_NAME}_tests" PRIVATE + "-Wall" + "-Wextra" + "-Werror" + "-pedantic-errors" + ) + + discover_tests(TARGET "${PROJECT_NAME}_tests") + + add_custom_target("run_all_tests" + COMMAND ${CMAKE_CTEST_COMMAND} "--output-on-failure" + WORKING_DIRECTORY ${PROJECT_BINARY_DIR} + DEPENDS "newtype_tests" + COMMENT "Running unit tests" + ) +endif() + +# 'newtype' docs + +option(BUILD_DOCS "Build the library documentation" OFF) + +if(BUILD_DOCS) + find_program(PIPENV_EXE NAMES "pipenv3" "pipenv") + if(NOT PIPENV_EXE) + message(FATAL_ERROR "Could not find pipenv") + endif() + + add_custom_target("docs" ALL + DEPENDS "${PROJECT_BINARY_DIR}/doc/html/index.html" "${PROJECT_BINARY_DIR}/doc/man/newtype.3" + ) + + add_custom_command(OUTPUT "${PROJECT_BINARY_DIR}/doc/html/index.html" + COMMAND "${PIPENV_EXE}" "run" "sphinx-build" "-b" "singlehtml" "${PROJECT_SOURCE_DIR}/doc/src" "${PROJECT_BINARY_DIR}/doc/html" ">/dev/null" + DEPENDS "${PROJECT_SOURCE_DIR}/doc/src/index.rst" "${PROJECT_SOURCE_DIR}/doc/src/conf.py" + WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}/doc" + COMMENT "Compiling HTML documentation" + ) + + add_custom_command(OUTPUT "${PROJECT_BINARY_DIR}/doc/man/newtype.3" + COMMAND "${PIPENV_EXE}" "run" "sphinx-build" "-b" "man" "${PROJECT_SOURCE_DIR}/doc/src" "${PROJECT_BINARY_DIR}/doc/man" ">/dev/null" + DEPENDS "${PROJECT_SOURCE_DIR}/doc/src/index.rst" "${PROJECT_SOURCE_DIR}/doc/src/conf.py" + WORKING_DIRECTORY "${PROJECT_SOURCE_DIR}/doc" + COMMENT "Compiling man pages" + ) + + install(DIRECTORY "${PROJECT_BINARY_DIR}/doc/html" + DESTINATION "share/doc/${PROJECT_NAME}" + PATTERN ".nojekyll" EXCLUDE + PATTERN ".buildinfo" EXCLUDE + PATTERN ".doctrees" EXCLUDE + PATTERN "objects.inv" EXCLUDE + ) + + install(FILES "${PROJECT_BINARY_DIR}/doc/man/${PROJECT_NAME}.3" + DESTINATION "share/man/man3" + ) + endif() + +# CMake support files + +write_basic_package_version_file( + "${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" + COMPATIBILITY "AnyNewerVersion" +) + +configure_package_config_file( + "${PROJECT_SOURCE_DIR}/cmake/config.cmake.in" + "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" + INSTALL_DESTINATION "lib/cmake/${PROJECT_NAME}" +) + +install(FILES + "${PROJECT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake" + "${PROJECT_BINARY_DIR}/${PROJECT_NAME}Config.cmake" + DESTINATION "lib/cmake/${PROJECT_NAME}" +) + +install(EXPORT "${PROJECT_NAME}Targets" + DESTINATION "lib/cmake/${PROJECT_NAME}" +) @@ -0,0 +1,26 @@ +Copyright (c) 2019, Felix Morgner <felix.morgner@gmail.com>, all rights reserved + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + - Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + - Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + - Neither the name of the copyright holders nor the names of its contributors may + be used to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/cmake/Modules/Conan.cmake b/cmake/Modules/Conan.cmake new file mode 100644 index 0000000..aac3b9c --- /dev/null +++ b/cmake/Modules/Conan.cmake @@ -0,0 +1,554 @@ +# The MIT License (MIT) + +# Copyright (c) 2018 JFrog + +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + + + +# This file comes from: https://github.com/conan-io/cmake-conan. Please refer +# to this repository for issues and documentation. + +# Its purpose is to wrap and launch Conan C/C++ Package Manager when cmake is called. +# It will take CMake current settings (os, compiler, compiler version, architecture) +# and translate them to conan settings for installing and retrieving dependencies. + +# It is intended to facilitate developers building projects that have conan dependencies, +# but it is only necessary on the end-user side. It is not necessary to create conan +# packages, in fact it shouldn't be use for that. Check the project documentation. + + +include(CMakeParseArguments) + +function(_get_msvc_ide_version result) + set(${result} "" PARENT_SCOPE) + if(NOT MSVC_VERSION VERSION_LESS 1400 AND MSVC_VERSION VERSION_LESS 1500) + set(${result} 8 PARENT_SCOPE) + elseif(NOT MSVC_VERSION VERSION_LESS 1500 AND MSVC_VERSION VERSION_LESS 1600) + set(${result} 9 PARENT_SCOPE) + elseif(NOT MSVC_VERSION VERSION_LESS 1600 AND MSVC_VERSION VERSION_LESS 1700) + set(${result} 10 PARENT_SCOPE) + elseif(NOT MSVC_VERSION VERSION_LESS 1700 AND MSVC_VERSION VERSION_LESS 1800) + set(${result} 11 PARENT_SCOPE) + elseif(NOT MSVC_VERSION VERSION_LESS 1800 AND MSVC_VERSION VERSION_LESS 1900) + set(${result} 12 PARENT_SCOPE) + elseif(NOT MSVC_VERSION VERSION_LESS 1900 AND MSVC_VERSION VERSION_LESS 1910) + set(${result} 14 PARENT_SCOPE) + elseif(NOT MSVC_VERSION VERSION_LESS 1910 AND MSVC_VERSION VERSION_LESS 1920) + set(${result} 15 PARENT_SCOPE) + elseif(NOT MSVC_VERSION VERSION_LESS 1920 AND MSVC_VERSION VERSION_LESS 1930) + set(${result} 16 PARENT_SCOPE) + else() + message(FATAL_ERROR "Conan: Unknown MSVC compiler version [${MSVC_VERSION}]") + endif() +endfunction() + +function(conan_cmake_settings result) + #message(STATUS "COMPILER " ${CMAKE_CXX_COMPILER}) + #message(STATUS "COMPILER " ${CMAKE_CXX_COMPILER_ID}) + #message(STATUS "VERSION " ${CMAKE_CXX_COMPILER_VERSION}) + #message(STATUS "FLAGS " ${CMAKE_LANG_FLAGS}) + #message(STATUS "LIB ARCH " ${CMAKE_CXX_LIBRARY_ARCHITECTURE}) + #message(STATUS "BUILD TYPE " ${CMAKE_BUILD_TYPE}) + #message(STATUS "GENERATOR " ${CMAKE_GENERATOR}) + #message(STATUS "GENERATOR WIN64 " ${CMAKE_CL_64}) + + message(STATUS "Conan: Automatic detection of conan settings from cmake") + + parse_arguments(${ARGV}) + + if(ARGUMENTS_BUILD_TYPE) + set(_CONAN_SETTING_BUILD_TYPE ${ARGUMENTS_BUILD_TYPE}) + elseif(CMAKE_BUILD_TYPE) + set(_CONAN_SETTING_BUILD_TYPE ${CMAKE_BUILD_TYPE}) + else() + message(FATAL_ERROR "Please specify in command line CMAKE_BUILD_TYPE (-DCMAKE_BUILD_TYPE=Release)") + endif() + + string(TOUPPER ${_CONAN_SETTING_BUILD_TYPE} _CONAN_SETTING_BUILD_TYPE_UPPER) + if (_CONAN_SETTING_BUILD_TYPE_UPPER STREQUAL "DEBUG") + set(_CONAN_SETTING_BUILD_TYPE "Debug") + elseif(_CONAN_SETTING_BUILD_TYPE_UPPER STREQUAL "RELEASE") + set(_CONAN_SETTING_BUILD_TYPE "Release") + elseif(_CONAN_SETTING_BUILD_TYPE_UPPER STREQUAL "RELWITHDEBINFO") + set(_CONAN_SETTING_BUILD_TYPE "RelWithDebInfo") + elseif(_CONAN_SETTING_BUILD_TYPE_UPPER STREQUAL "MINSIZEREL") + set(_CONAN_SETTING_BUILD_TYPE "MinSizeRel") + endif() + + if(ARGUMENTS_ARCH) + set(_CONAN_SETTING_ARCH ${ARGUMENTS_ARCH}) + endif() + #handle -s os setting + if(CMAKE_SYSTEM_NAME) + #use default conan os setting if CMAKE_SYSTEM_NAME is not defined + set(CONAN_SYSTEM_NAME ${CMAKE_SYSTEM_NAME}) + if(${CMAKE_SYSTEM_NAME} STREQUAL "Darwin") + set(CONAN_SYSTEM_NAME Macos) + endif() + set(CONAN_SUPPORTED_PLATFORMS Windows Linux Macos Android iOS FreeBSD WindowsStore) + list (FIND CONAN_SUPPORTED_PLATFORMS "${CONAN_SYSTEM_NAME}" _index) + if (${_index} GREATER -1) + #check if the cmake system is a conan supported one + set(_CONAN_SETTING_OS ${CONAN_SYSTEM_NAME}) + else() + message(FATAL_ERROR "cmake system ${CONAN_SYSTEM_NAME} is not supported by conan. Use one of ${CONAN_SUPPORTED_PLATFORMS}") + endif() + endif() + + get_property(_languages GLOBAL PROPERTY ENABLED_LANGUAGES) + if (";${_languages};" MATCHES ";CXX;") + set(LANGUAGE CXX) + set(USING_CXX 1) + elseif (";${_languages};" MATCHES ";C;") + set(LANGUAGE C) + set(USING_CXX 0) + else () + message(FATAL_ERROR "Conan: Neither C or C++ was detected as a language for the project. Unabled to detect compiler version.") + endif() + + if (${CMAKE_${LANGUAGE}_COMPILER_ID} STREQUAL GNU) + # using GCC + # TODO: Handle other params + string(REPLACE "." ";" VERSION_LIST ${CMAKE_${LANGUAGE}_COMPILER_VERSION}) + list(GET VERSION_LIST 0 MAJOR) + list(GET VERSION_LIST 1 MINOR) + set(COMPILER_VERSION ${MAJOR}.${MINOR}) + if(${MAJOR} GREATER 4) + set(COMPILER_VERSION ${MAJOR}) + endif() + set(_CONAN_SETTING_COMPILER gcc) + set(_CONAN_SETTING_COMPILER_VERSION ${COMPILER_VERSION}) + if (USING_CXX) + conan_cmake_detect_unix_libcxx(_LIBCXX) + set(_CONAN_SETTING_COMPILER_LIBCXX ${_LIBCXX}) + endif () + elseif (${CMAKE_${LANGUAGE}_COMPILER_ID} STREQUAL AppleClang) + # using AppleClang + string(REPLACE "." ";" VERSION_LIST ${CMAKE_${LANGUAGE}_COMPILER_VERSION}) + list(GET VERSION_LIST 0 MAJOR) + list(GET VERSION_LIST 1 MINOR) + set(_CONAN_SETTING_COMPILER apple-clang) + set(_CONAN_SETTING_COMPILER_VERSION ${MAJOR}.${MINOR}) + if (USING_CXX) + conan_cmake_detect_unix_libcxx(_LIBCXX) + set(_CONAN_SETTING_COMPILER_LIBCXX ${_LIBCXX}) + endif () + elseif (${CMAKE_${LANGUAGE}_COMPILER_ID} STREQUAL Clang) + string(REPLACE "." ";" VERSION_LIST ${CMAKE_${LANGUAGE}_COMPILER_VERSION}) + list(GET VERSION_LIST 0 MAJOR) + list(GET VERSION_LIST 1 MINOR) + set(_CONAN_SETTING_COMPILER clang) + set(_CONAN_SETTING_COMPILER_VERSION ${MAJOR}.${MINOR}) + if(APPLE) + cmake_policy(GET CMP0025 APPLE_CLANG_POLICY_ENABLED) + if(NOT APPLE_CLANG_POLICY_ENABLED) + message(STATUS "Conan: APPLE and Clang detected. Assuming apple-clang compiler. Set CMP0025 to avoid it") + set(_CONAN_SETTING_COMPILER apple-clang) + endif() + endif() + if(${_CONAN_SETTING_COMPILER} STREQUAL clang AND ${MAJOR} GREATER 7) + set(_CONAN_SETTING_COMPILER_VERSION ${MAJOR}) + endif() + if (USING_CXX) + conan_cmake_detect_unix_libcxx(_LIBCXX) + set(_CONAN_SETTING_COMPILER_LIBCXX ${_LIBCXX}) + endif () + elseif(${CMAKE_${LANGUAGE}_COMPILER_ID} STREQUAL MSVC) + set(_VISUAL "Visual Studio") + _get_msvc_ide_version(_VISUAL_VERSION) + if("${_VISUAL_VERSION}" STREQUAL "") + message(FATAL_ERROR "Conan: Visual Studio not recognized") + else() + set(_CONAN_SETTING_COMPILER ${_VISUAL}) + set(_CONAN_SETTING_COMPILER_VERSION ${_VISUAL_VERSION}) + endif() + + if(NOT _CONAN_SETTING_ARCH) + if (MSVC_${LANGUAGE}_ARCHITECTURE_ID MATCHES "64") + set(_CONAN_SETTING_ARCH x86_64) + elseif (MSVC_${LANGUAGE}_ARCHITECTURE_ID MATCHES "^ARM") + message(STATUS "Conan: Using default ARM architecture from MSVC") + set(_CONAN_SETTING_ARCH armv6) + elseif (MSVC_${LANGUAGE}_ARCHITECTURE_ID MATCHES "86") + set(_CONAN_SETTING_ARCH x86) + else () + message(FATAL_ERROR "Conan: Unknown MSVC architecture [${MSVC_${LANGUAGE}_ARCHITECTURE_ID}]") + endif() + endif() + + conan_cmake_detect_vs_runtime(_vs_runtime) + message(STATUS "Conan: Detected VS runtime: ${_vs_runtime}") + set(_CONAN_SETTING_COMPILER_RUNTIME ${_vs_runtime}) + + if (CMAKE_GENERATOR_TOOLSET) + set(_CONAN_SETTING_COMPILER_TOOLSET ${CMAKE_VS_PLATFORM_TOOLSET}) + elseif(CMAKE_VS_PLATFORM_TOOLSET AND (CMAKE_GENERATOR STREQUAL "Ninja")) + set(_CONAN_SETTING_COMPILER_TOOLSET ${CMAKE_VS_PLATFORM_TOOLSET}) + endif() + else() + message(FATAL_ERROR "Conan: compiler setup not recognized") + endif() + + # If profile is defined it is used + if(CMAKE_BUILD_TYPE STREQUAL "Debug" AND ARGUMENTS_DEBUG_PROFILE) + set(_APPLIED_PROFILES ${ARGUMENTS_DEBUG_PROFILE}) + elseif(CMAKE_BUILD_TYPE STREQUAL "Release" AND ARGUMENTS_RELEASE_PROFILE) + set(_APPLIED_PROFILES ${ARGUMENTS_RELEASE_PROFILE}) + elseif(CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo" AND ARGUMENTS_RELWITHDEBINFO_PROFILE) + set(_APPLIED_PROFILES ${ARGUMENTS_RELWITHDEBINFO_PROFILE}) + elseif(CMAKE_BUILD_TYPE STREQUAL "MinSizeRel" AND ARGUMENTS_MINSIZEREL_PROFILE) + set(_APPLIED_PROFILES ${ARGUMENTS_MINSIZEREL_PROFILE}) + elseif(ARGUMENTS_PROFILE) + set(_APPLIED_PROFILES ${ARGUMENTS_PROFILE}) + endif() + + foreach(ARG ${_APPLIED_PROFILES}) + set(_SETTINGS ${_SETTINGS} -pr ${ARG}) + endforeach() + + if(NOT _SETTINGS OR ARGUMENTS_PROFILE_AUTO STREQUAL "ALL") + set(ARGUMENTS_PROFILE_AUTO arch build_type compiler compiler.version + compiler.runtime compiler.libcxx compiler.toolset) + endif() + + # Automatic from CMake + foreach(ARG ${ARGUMENTS_PROFILE_AUTO}) + string(TOUPPER ${ARG} _arg_name) + string(REPLACE "." "_" _arg_name ${_arg_name}) + if(_CONAN_SETTING_${_arg_name}) + set(_SETTINGS ${_SETTINGS} -s ${ARG}=${_CONAN_SETTING_${_arg_name}}) + endif() + endforeach() + + foreach(ARG ${ARGUMENTS_SETTINGS}) + set(_SETTINGS ${_SETTINGS} -s ${ARG}) + endforeach() + + message(STATUS "Conan: Settings= ${_SETTINGS}") + + set(${result} ${_SETTINGS} PARENT_SCOPE) +endfunction() + + +function(conan_cmake_detect_unix_libcxx result) + # Take into account any -stdlib in compile options + get_directory_property(compile_options DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMPILE_OPTIONS) + + # Take into account any _GLIBCXX_USE_CXX11_ABI in compile definitions + get_directory_property(defines DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} COMPILE_DEFINITIONS) + foreach(define ${defines}) + if(define MATCHES "_GLIBCXX_USE_CXX11_ABI") + if(define MATCHES "^-D") + set(compile_options ${compile_options} "${define}") + else() + set(compile_options ${compile_options} "-D${define}") + endif() + endif() + endforeach() + + execute_process( + COMMAND ${CMAKE_COMMAND} -E echo "#include <string>" + COMMAND ${CMAKE_CXX_COMPILER} -x c++ ${compile_options} -E -dM - + OUTPUT_VARIABLE string_defines + ) + + if(string_defines MATCHES "#define __GLIBCXX__") + # Allow -D_GLIBCXX_USE_CXX11_ABI=ON/OFF as argument to cmake + if(DEFINED _GLIBCXX_USE_CXX11_ABI) + if(_GLIBCXX_USE_CXX11_ABI) + set(${result} libstdc++11 PARENT_SCOPE) + return() + else() + set(${result} libstdc++ PARENT_SCOPE) + return() + endif() + endif() + + if(string_defines MATCHES "#define _GLIBCXX_USE_CXX11_ABI 1\n") + set(${result} libstdc++11 PARENT_SCOPE) + else() + # Either the compiler is missing the define because it is old, and so + # it can't use the new abi, or the compiler was configured to use the + # old abi by the user or distro (e.g. devtoolset on RHEL/CentOS) + set(${result} libstdc++ PARENT_SCOPE) + endif() + else() + set(${result} libc++ PARENT_SCOPE) + endif() +endfunction() + +function(conan_cmake_detect_vs_runtime result) + string(TOUPPER ${CMAKE_BUILD_TYPE} build_type) + set(variables CMAKE_CXX_FLAGS_${build_type} CMAKE_C_FLAGS_${build_type} CMAKE_CXX_FLAGS CMAKE_C_FLAGS) + foreach(variable ${variables}) + string(REPLACE " " ";" flags ${${variable}}) + foreach (flag ${flags}) + if(${flag} STREQUAL "/MD" OR ${flag} STREQUAL "/MDd" OR ${flag} STREQUAL "/MT" OR ${flag} STREQUAL "/MTd") + string(SUBSTRING ${flag} 1 -1 runtime) + set(${result} ${runtime} PARENT_SCOPE) + return() + endif() + endforeach() + endforeach() + if(${build_type} STREQUAL "DEBUG") + set(${result} "MDd" PARENT_SCOPE) + else() + set(${result} "MD" PARENT_SCOPE) + endif() +endfunction() + + +macro(parse_arguments) + set(options BASIC_SETUP CMAKE_TARGETS UPDATE KEEP_RPATHS NO_LOAD NO_OUTPUT_DIRS OUTPUT_QUIET NO_IMPORTS) + set(oneValueArgs CONANFILE ARCH BUILD_TYPE INSTALL_FOLDER CONAN_COMMAND) + set(multiValueArgs DEBUG_PROFILE RELEASE_PROFILE RELWITHDEBINFO_PROFILE MINSIZEREL_PROFILE + PROFILE REQUIRES OPTIONS IMPORTS SETTINGS BUILD ENV GENERATORS PROFILE_AUTO + INSTALL_ARGS) + cmake_parse_arguments(ARGUMENTS "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN}) +endmacro() + +function(conan_cmake_install) + # Calls "conan install" + # Argument BUILD is equivalant to --build={missing, PkgName,...} or + # --build when argument is 'BUILD all' (which builds all packages from source) + # Argument CONAN_COMMAND, to specify the conan path, e.g. in case of running from source + # cmake does not identify conan as command, even if it is +x and it is in the path + parse_arguments(${ARGV}) + + if(CONAN_CMAKE_MULTI) + set(ARGUMENTS_GENERATORS ${ARGUMENTS_GENERATORS} cmake_multi) + else() + set(ARGUMENTS_GENERATORS ${ARGUMENTS_GENERATORS} cmake) + endif() + + set(CONAN_BUILD_POLICY "") + foreach(ARG ${ARGUMENTS_BUILD}) + if(${ARG} STREQUAL "all") + set(CONAN_BUILD_POLICY ${CONAN_BUILD_POLICY} --build) + break() + else() + set(CONAN_BUILD_POLICY ${CONAN_BUILD_POLICY} --build=${ARG}) + endif() + endforeach() + if(ARGUMENTS_CONAN_COMMAND) + set(conan_command ${ARGUMENTS_CONAN_COMMAND}) + else() + set(conan_command conan) + endif() + set(CONAN_OPTIONS "") + if(ARGUMENTS_CONANFILE) + set(CONANFILE ${CMAKE_CURRENT_SOURCE_DIR}/${ARGUMENTS_CONANFILE}) + # A conan file has been specified - apply specified options as well if provided + foreach(ARG ${ARGUMENTS_OPTIONS}) + set(CONAN_OPTIONS ${CONAN_OPTIONS} -o=${ARG}) + endforeach() + else() + set(CONANFILE ".") + endif() + if(ARGUMENTS_UPDATE) + set(CONAN_INSTALL_UPDATE --update) + endif() + if(ARGUMENTS_NO_IMPORTS) + set(CONAN_INSTALL_NO_IMPORTS --no-imports) + endif() + set(CONAN_INSTALL_FOLDER "") + if(ARGUMENTS_INSTALL_FOLDER) + set(CONAN_INSTALL_FOLDER -if=${ARGUMENTS_INSTALL_FOLDER}) + endif() + foreach(ARG ${ARGUMENTS_GENERATORS}) + set(CONAN_GENERATORS ${CONAN_GENERATORS} -g=${ARG}) + endforeach() + foreach(ARG ${ARGUMENTS_ENV}) + set(CONAN_ENV_VARS ${CONAN_ENV_VARS} -e=${ARG}) + endforeach() + set(conan_args install ${CONANFILE} ${settings} ${CONAN_ENV_VARS} ${CONAN_GENERATORS} ${CONAN_BUILD_POLICY} ${CONAN_INSTALL_UPDATE} ${CONAN_INSTALL_NO_IMPORTS} ${CONAN_OPTIONS} ${CONAN_INSTALL_FOLDER} ${ARGUMENTS_INSTALL_ARGS}) + + string (REPLACE ";" " " _conan_args "${conan_args}") + message(STATUS "Conan executing: ${conan_command} ${_conan_args}") + + if(ARGUMENTS_OUTPUT_QUIET) + execute_process(COMMAND ${conan_command} ${conan_args} + RESULT_VARIABLE return_code + OUTPUT_VARIABLE conan_output + ERROR_VARIABLE conan_output + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + else() + execute_process(COMMAND ${conan_command} ${conan_args} + RESULT_VARIABLE return_code + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) + endif() + + if(NOT "${return_code}" STREQUAL "0") + message(FATAL_ERROR "Conan install failed='${return_code}'") + endif() + +endfunction() + + +function(conan_cmake_setup_conanfile) + parse_arguments(${ARGV}) + if(ARGUMENTS_CONANFILE) + get_filename_component(_CONANFILE_NAME ${ARGUMENTS_CONANFILE} NAME) + # configure_file will make sure cmake re-runs when conanfile is updated + configure_file(${ARGUMENTS_CONANFILE} ${CMAKE_CURRENT_BINARY_DIR}/${_CONANFILE_NAME}.junk) + file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/${_CONANFILE_NAME}.junk) + else() + conan_cmake_generate_conanfile(${ARGV}) + endif() +endfunction() + +function(conan_cmake_generate_conanfile) + # Generate, writing in disk a conanfile.txt with the requires, options, and imports + # specified as arguments + # This will be considered as temporary file, generated in CMAKE_CURRENT_BINARY_DIR) + parse_arguments(${ARGV}) + set(_FN "${CMAKE_CURRENT_BINARY_DIR}/conanfile.txt") + + file(WRITE ${_FN} "[generators]\ncmake\n\n[requires]\n") + foreach(ARG ${ARGUMENTS_REQUIRES}) + file(APPEND ${_FN} ${ARG} "\n") + endforeach() + + file(APPEND ${_FN} ${ARG} "\n[options]\n") + foreach(ARG ${ARGUMENTS_OPTIONS}) |
