├── example ├── examples.hpp ├── CMakeLists.txt ├── tuple_cat.cpp └── tutorial_snippets.cpp ├── test ├── CMakeLists.txt ├── simple_test.hpp └── meta.cpp ├── .gitmodules ├── readme.md ├── FindMeta.cmake ├── LICENSE.md ├── appveyor.yml ├── .clang-format ├── doc ├── CMakeLists.txt ├── Doxyfile.in ├── layout.xml └── index.md ├── CMakeLists.txt ├── install_libcxx.sh ├── .gitignore ├── .travis.yml └── include └── meta └── meta_fwd.hpp /example/examples.hpp: -------------------------------------------------------------------------------- 1 | /// \file examples.hpp List of all examples 2 | 3 | /// \example tuple_cat.cpp Tuple concatenation example: 4 | -------------------------------------------------------------------------------- /test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(test.meta meta.cpp) 2 | target_link_libraries(test.meta meta) 3 | add_test(test.meta test.meta) 4 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "doc/gh-pages"] 2 | path = doc/gh-pages 3 | url = https://github.com/ericniebler/meta.git 4 | branch = gh-pages 5 | -------------------------------------------------------------------------------- /example/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(tutorial_snippets tutorial_snippets.cpp) 2 | target_link_libraries(tutorial_snippets meta) 3 | add_test(example.tutorial_snippets tutorial_snippets) 4 | 5 | add_executable(tuple_cat tuple_cat.cpp) 6 | target_link_libraries(tuple_cat meta) 7 | add_test(example.tuple_cat tuple_cat) 8 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- 1 | # Meta: A tiny metaprogramming library 2 | 3 | [![Build Status](https://travis-ci.org/ericniebler/meta.svg?branch=master)](https://travis-ci.org/ericniebler/meta) 4 | 5 | *Meta* is a tiny and header-only C++11 metaprogramming library released under the 6 | Boost Software License. Supported compilers are clang >= 3.4 and gcc >= 4.9. To compile with meta you just have to: 7 | 8 | ```.cpp 9 | #include 10 | ``` 11 | 12 | You can find documentation online [here](https://ericniebler.github.io/meta/index.html). 13 | 14 | For a quick start see Eric Niebler's blog post: 15 | [A tiny metaprogramming library](http://ericniebler.com/2014/11/13/tiny-metaprogramming-library/). (Note: the names in Meta are different from those describe in the blog post, but the overall design remains the same.) 16 | 17 | To generate the up-to-date tutorial and documentation run `make doc` in the 18 | build directory (requires Doxygen, LaTeX, dvips, ghostscript). 19 | -------------------------------------------------------------------------------- /FindMeta.cmake: -------------------------------------------------------------------------------- 1 | # Find the Meta include directory 2 | # The following variables are set if Meta is found. 3 | # Meta_FOUND - True when the Meta include directory is found. 4 | # Meta_INCLUDE_DIR - The path to where the meta include files are. 5 | # If Meta is not found, Meta_FOUND is set to false. 6 | 7 | find_package(PkgConfig) 8 | 9 | if(NOT EXISTS "${Meta_INCLUDE_DIR}") 10 | find_path(Meta_INCLUDE_DIR 11 | NAMES meta/meta.hpp 12 | DOC "Meta library header files" 13 | ) 14 | endif() 15 | 16 | if(EXISTS "${Meta_INCLUDE_DIR}") 17 | include(FindPackageHandleStandardArgs) 18 | mark_as_advanced(Meta_INCLUDE_DIR) 19 | else() 20 | include(ExternalProject) 21 | ExternalProject_Add(meta 22 | GIT_REPOSITORY https://github.com/ericniebler/meta.git 23 | TIMEOUT 5 24 | CMAKE_ARGS -DCMAKE_CXX_COMPILER=${CMAKE_CXX_COMPILER} -DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS} 25 | PREFIX "${CMAKE_CURRENT_BINARY_DIR}" 26 | INSTALL_COMMAND "" # Disable install step 27 | ) 28 | 29 | # Specify include dir 30 | ExternalProject_Get_Property(meta source_dir) 31 | set(Meta_INCLUDE_DIR ${source_dir}/include) 32 | endif() 33 | 34 | if(EXISTS "${Meta_INCLUDE_DIR}") 35 | set(Meta_FOUND 1) 36 | else() 37 | set(Meta_FOUND 0) 38 | endif() 39 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # Boost Software License - Version 1.0 - August 17th, 2003 2 | 3 | Permission is hereby granted, free of charge, to any person or organization 4 | obtaining a copy of the software and accompanying documentation covered by 5 | this license (the "Software") to use, reproduce, display, distribute, 6 | execute, and transmit the Software, and to prepare derivative works of the 7 | Software, and to permit third-parties to whom the Software is furnished to 8 | do so, all subject to the following: 9 | 10 | The copyright notices in the Software and this entire statement, including 11 | the above license grant, this restriction and the following disclaimer, 12 | must be included in all copies of the Software, in whole or in part, and 13 | all derivative works of the Software, unless such copies or derivative 14 | works are solely in the form of machine-executable object code generated by 15 | a source language processor. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 20 | SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 21 | FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | DEALINGS IN THE SOFTWARE. 24 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | shallow_clone: true 2 | 3 | image: Visual Studio 2017 4 | 5 | platform: 6 | - x64_x86 7 | - x64 8 | 9 | configuration: 10 | - Debug 11 | - Release 12 | 13 | environment: 14 | matrix: 15 | - CXX: clang-cl 16 | CPP: latest 17 | 18 | - CXX: cl 19 | CPP: latest 20 | 21 | cache: 22 | - C:\ninja-1.8.2 23 | 24 | install: 25 | - ps: | 26 | if (![IO.File]::Exists("C:\ninja-1.8.2\ninja.exe")) { 27 | Start-FileDownload 'https://github.com/ninja-build/ninja/releases/download/v1.8.2/ninja-win.zip' 28 | 7z x -y ninja-win.zip -oC:\ninja-1.8.2 29 | } 30 | $env:PATH="C:\ninja-1.8.2;$env:PATH" 31 | - for /f "tokens=1* delims=" %%i in ('"%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -latest -property installationPath') do call "%%i\VC\Auxiliary\Build\vcvarsall.bat" %PLATFORM% 32 | - cmake --version 33 | - ninja --version 34 | - clang-cl --version 35 | - cl /Bv || exit 0 36 | 37 | build_script: 38 | - mkdir build && cd build 39 | - ps: | 40 | $env:CC=$env:CXX 41 | if (($env:CXX -eq "clang-cl") -and (-not ($env:PLATFORM -eq "x64"))) { 42 | $env:CXXFLAGS='-m32' 43 | $env:CFLAGS='-m32' 44 | } 45 | - cmake .. -G Ninja -Wdev -DCMAKE_BUILD_TYPE=%CONFIGURATION% -DMETA_CXX_STD=%CPP% 46 | - ninja -v 47 | 48 | test_script: 49 | - ctest -j2 --output-on-failure 50 | 51 | deploy: off 52 | -------------------------------------------------------------------------------- /.clang-format: -------------------------------------------------------------------------------- 1 | BasedOnStyle: Google 2 | AccessModifierOffset: -4 3 | AlignEscapedNewlinesLeft: true 4 | AlignTrailingComments: true 5 | AllowAllParametersOfDeclarationOnNextLine: true 6 | AllowShortBlocksOnASingleLine: false 7 | AllowShortFunctionsOnASingleLine: Inline 8 | AllowShortIfStatementsOnASingleLine: false 9 | AllowShortLoopsOnASingleLine: false 10 | AlwaysBreakBeforeMultilineStrings: false 11 | AlwaysBreakTemplateDeclarations: true 12 | BinPackParameters: true 13 | BreakBeforeBinaryOperators: false 14 | BreakBeforeBraces: Allman 15 | BreakBeforeTernaryOperators: true 16 | BreakConstructorInitializersBeforeComma: true 17 | ColumnLimit: 100 18 | ConstructorInitializerAllOnOneLineOrOnePerLine: true 19 | ConstructorInitializerIndentWidth: 2 20 | ContinuationIndentWidth: 4 21 | Cpp11BracedListStyle: true 22 | DerivePointerBinding: false 23 | ExperimentalAutoDetectBinPacking: false 24 | IndentCaseLabels: false 25 | IndentFunctionDeclarationAfterType: true 26 | IndentWidth: 4 27 | KeepEmptyLinesAtTheStartOfBlocks: false 28 | Language: Cpp 29 | MaxEmptyLinesToKeep: 1 30 | NamespaceIndentation: All 31 | PenaltyBreakBeforeFirstCallParameter: 10 32 | PointerBindsToType: false 33 | SpaceAfterControlStatementKeyword: false 34 | SpaceBeforeAssignmentOperators: true 35 | SpaceBeforeParens: Never 36 | SpaceInEmptyParentheses: false 37 | SpacesBeforeTrailingComments: 1 38 | SpacesInCStyleCastParentheses: false 39 | SpacesInParentheses: false 40 | SpacesInAngles: false 41 | Standard: Cpp11 42 | TabWidth: 4 43 | UseTab: Never 44 | -------------------------------------------------------------------------------- /doc/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | #============================================================================= 2 | # Setup the documentation 3 | #============================================================================= 4 | find_package(Doxygen) 5 | find_package(Git) 6 | 7 | if (NOT DOXYGEN_FOUND) 8 | message(STATUS 9 | "Doxygen not found; the 'doc' and 'gh-pages.{clean,copy,update}' targets " 10 | "will be unavailable.") 11 | return() 12 | endif() 13 | 14 | configure_file(Doxyfile.in Doxyfile @ONLY) 15 | add_custom_target(doc.check 16 | COMMAND ${DOXYGEN_EXECUTABLE} Doxyfile 17 | COMMENT "Running Doxygen to validate the documentation" 18 | VERBATIM 19 | ) 20 | 21 | 22 | add_custom_target(doc 23 | COMMAND ${DOXYGEN_EXECUTABLE} Doxyfile 24 | COMMENT "Generating API documentation with Doxygen" 25 | # DEPENDS benchmarks 26 | VERBATIM 27 | ) 28 | 29 | if (NOT GIT_FOUND) 30 | message(STATUS 31 | "Git was not found; the 'gh-pages.{clean,copy,update}' targets " 32 | "will be unavailable.") 33 | return() 34 | endif() 35 | 36 | add_custom_target(gh-pages.clean 37 | COMMAND ${CMAKE_COMMAND} -E remove *.png *.css *.js *.html 38 | COMMAND ${CMAKE_COMMAND} -E remove_directory search 39 | WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/gh-pages 40 | COMMENT "Cleaning up doc/gh-pages" 41 | VERBATIM 42 | ) 43 | 44 | add_custom_target(gh-pages.copy 45 | COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_CURRENT_BINARY_DIR}/html ${CMAKE_CURRENT_LIST_DIR}/gh-pages 46 | WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/gh-pages 47 | COMMENT "Copying the documentation from ${CMAKE_CURRENT_BINARY_DIR}/html to doc/gh-pages" 48 | DEPENDS doc gh-pages.clean 49 | VERBATIM 50 | ) 51 | 52 | execute_process( 53 | COMMAND ${GIT_EXECUTABLE} rev-parse --short HEAD 54 | OUTPUT_VARIABLE META_GIT_SHORT_SHA 55 | OUTPUT_STRIP_TRAILING_WHITESPACE 56 | ) 57 | 58 | add_custom_target(gh-pages.update 59 | COMMAND ${GIT_EXECUTABLE} add --all . 60 | COMMAND ${GIT_EXECUTABLE} commit -m "Update to ${META_GIT_SHORT_SHA}" 61 | WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR}/gh-pages 62 | COMMENT "Updating the gh-pages branch with freshly built documentation" 63 | DEPENDS gh-pages.copy 64 | VERBATIM 65 | ) 66 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.6) 2 | get_directory_property(is_subproject PARENT_DIRECTORY) 3 | 4 | project(Meta CXX) 5 | 6 | set(CMAKE_EXPORT_COMPILE_COMMANDS ON) # Export compilation data-base 7 | 8 | set(META_CXX_STD 11 CACHE STRING "C++ standard version.") 9 | 10 | add_library(meta INTERFACE) 11 | target_include_directories(meta INTERFACE $) 12 | target_include_directories(meta SYSTEM INTERFACE $/include>) 13 | 14 | include(CTest) # invokes enable_testing() and defines BUILD_TESTING variable, defaulting to ON 15 | 16 | if("x${CMAKE_CXX_COMPILER_ID}" MATCHES "x.*Clang") 17 | if("x${CMAKE_CXX_SIMULATE_ID}" STREQUAL "xMSVC") 18 | set(META_CXX_COMPILER_CLANGCL TRUE) 19 | else() 20 | set(META_CXX_COMPILER_CLANG TRUE) 21 | endif() 22 | elseif(CMAKE_COMPILER_IS_GNUCXX) 23 | set(META_CXX_COMPILER_GCC TRUE) 24 | elseif("x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xMSVC") 25 | set(META_CXX_COMPILER_MSVC TRUE) 26 | endif() 27 | 28 | if(META_CXX_COMPILER_CLANGCL OR META_CXX_COMPILER_MSVC) 29 | # Clang-CL will blow up in the standard library if compiling with less than 30 | # C++14, and MSVC doesn't support less than C++14 at all. 31 | if(META_CXX_STD LESS 14) 32 | set(META_CXX_STD 14) 33 | endif() 34 | # MSVC is currently supported only in 17+ mode 35 | if(META_CXX_COMPILER_MSVC AND META_CXX_STD LESS 17) 36 | set(META_CXX_STD 17) 37 | endif() 38 | set(CMAKE_CXX_FLAGS "/std:c++${META_CXX_STD} /permissive- /WX ${CMAKE_CXX_FLAGS}") 39 | elseif(META_CXX_COMPILER_CLANG) 40 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++${META_CXX_STD} -ftemplate-backtrace-limit=0") 41 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Weverything -Werror -pedantic-errors -Wdocumentation") 42 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-old-style-cast") 43 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-documentation-unknown-command -Wno-missing-prototypes") 44 | set(CMAKE_CXX_FLAGS_DEBUG "-O0 -fno-inline -g3 -fstack-protector-all") 45 | set(CMAKE_CXX_FLAGS_RELEASE "-Ofast -g0 -march=native -mtune=native -DNDEBUG") 46 | elseif(META_CXX_COMPILER_GCC) 47 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++${META_CXX_STD} -ftemplate-backtrace-limit=0") 48 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -pedantic -Werror -pedantic-errors") 49 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-error=deprecated-declarations") 50 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-missing-field-initializers") 51 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wno-unused-parameter") 52 | set(CMAKE_CXX_FLAGS_DEBUG "-O0 -fno-inline -g3 -fstack-protector-all") 53 | set(CMAKE_CXX_FLAGS_RELEASE "-Ofast -g0 -march=native -mtune=native -DNDEBUG") 54 | endif() 55 | 56 | add_subdirectory(doc) 57 | add_subdirectory(example) 58 | add_subdirectory(test) 59 | 60 | if(EXISTS "${CMAKE_SOURCE_DIR}/scratch") 61 | add_subdirectory(scratch) 62 | endif() 63 | -------------------------------------------------------------------------------- /install_libcxx.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | TRUNK_VERSION="7.0.0" 4 | 5 | set -e 6 | 7 | # The pattern of clang --version is: clang version X.Y.Z (sometimes, see below). 8 | COMPILER_VERSION_OUTPUT="$($CXX --version)" 9 | arr=(${COMPILER_VERSION_OUTPUT// / }) 10 | 11 | COMPILER="${arr[0]}" 12 | VERSION="${arr[2]}" 13 | 14 | case $COMPILER in 15 | "clang") 16 | # Some Ubuntu clang builds are advertised as "just clang", but the 17 | # Version still follows the pattern: 3.6.2-svn240577-1~exp1 18 | # echo "Compiler is clang :)" 19 | arr2=(${VERSION//-/ }) 20 | VERSION="${arr2[0]}" 21 | ;; 22 | "Ubuntu") 23 | # Ubuntu renames _some_ (not all) of its clang compilers, the pattern of 24 | # clang --version is then: 25 | # Ubuntu clang version 3.6.2-svn240577-1~exp1 26 | COMPILER="${arr[1]}" 27 | VERSION="${arr[3]}" 28 | arr2=(${VERSION//-/ }) 29 | VERSION="${arr2[0]}" 30 | ;; 31 | *) 32 | echo "case did not match: compiler: ${COMPILER}" 33 | exit 1 34 | ;; 35 | esac 36 | 37 | if [ ${COMPILER} != "clang" ]; then 38 | echo "Error: trying to install libc++ for a compiler that is not clang: ${COMPILER}" 39 | exit 1 40 | fi 41 | 42 | if [ -z ${VERSION+x} ]; then 43 | echo "Malformed libc++ version - I give up." 44 | exit 4 45 | fi 46 | 47 | if [ ${VERSION} == $TRUNK_VERSION ]; then 48 | echo "Fetching libc++ and libc++abi tip-of-trunk..." 49 | 50 | # Checkout LLVM sources 51 | git clone --depth=1 https://github.com/llvm-mirror/llvm.git llvm-source 52 | git clone --depth=1 https://github.com/llvm-mirror/libcxx.git llvm-source/projects/libcxx 53 | git clone --depth=1 https://github.com/llvm-mirror/libcxxabi.git llvm-source/projects/libcxxabi 54 | else 55 | echo "Fetching libc++/libc++abi version: ${VERSION}..." 56 | LLVM_URL="http://releases.llvm.org/${VERSION}/llvm-${VERSION}.src.tar.xz" 57 | LIBCXX_URL="http://releases.llvm.org/${VERSION}/libcxx-${VERSION}.src.tar.xz" 58 | LIBCXXABI_URL="http://releases.llvm.org/${VERSION}/libcxxabi-${VERSION}.src.tar.xz" 59 | curl -O $LLVM_URL 60 | curl -O $LIBCXX_URL 61 | curl -O $LIBCXXABI_URL 62 | 63 | mkdir llvm-source 64 | mkdir llvm-source/projects 65 | mkdir llvm-source/projects/libcxx 66 | mkdir llvm-source/projects/libcxxabi 67 | 68 | tar -xf llvm-${VERSION}.src.tar.xz -C llvm-source --strip-components=1 69 | tar -xf libcxx-${VERSION}.src.tar.xz -C llvm-source/projects/libcxx --strip-components=1 70 | tar -xf libcxxabi-${VERSION}.src.tar.xz -C llvm-source/projects/libcxxabi --strip-components=1 71 | fi 72 | 73 | TARGET=`pwd`/llvm 74 | mkdir "${TARGET}" 75 | mkdir llvm-build 76 | cd llvm-build 77 | 78 | # - libc++ versions < 4.x do not have the install-cxxabi and install-cxx targets 79 | # - only ASAN is enabled for clang/libc++ versions < 4.x 80 | if [[ $VERSION == *"3."* ]]; then 81 | cmake -DCMAKE_C_COMPILER=${CC} -DCMAKE_CXX_COMPILER=${CXX} \ 82 | -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX="${TARGET}" \ 83 | ../llvm-source 84 | if [[ $SANITIZER == "Address;Undefined" ]]; then 85 | ASAN_FLAGS="-fsanitize=address" 86 | cmake -DCMAKE_CXX_FLAGS="${ASAN_FLAGS}" -DCMAKE_EXE_LINKER_FLAGS="${ASAN_FLAGS}" ../llvm-source 87 | fi 88 | make cxx -j2 VERBOSE=1 89 | mkdir "${TARGET}/lib" 90 | mkdir "${TARGET}/include" 91 | cp -r lib/* "${TARGET}/lib" 92 | cp -r include/c++ "${TARGET}/include" 93 | else 94 | cmake -DCMAKE_C_COMPILER=${CC} -DCMAKE_CXX_COMPILER=${CXX} \ 95 | -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_INSTALL_PREFIX="${TARGET}" \ 96 | -DLIBCXX_ABI_UNSTABLE=ON \ 97 | -DLLVM_USE_SANITIZER=${SANITIZER} \ 98 | ../llvm-source 99 | make cxx -j2 VERBOSE=1 100 | make install-cxxabi install-cxx 101 | fi 102 | 103 | exit 0 104 | -------------------------------------------------------------------------------- /doc/Doxyfile.in: -------------------------------------------------------------------------------- 1 | PROJECT_NAME = "Meta" 2 | PROJECT_BRIEF = "A tiny metaprogramming library" 3 | PROJECT_LOGO = 4 | PROJECT_NUMBER = 0.1 5 | 6 | STRIP_FROM_PATH = @Meta_SOURCE_DIR@/include 7 | BUILTIN_STL_SUPPORT = YES 8 | STRIP_FROM_INC_PATH = @Meta_SOURCE_DIR@/include 9 | ALIASES = 10 | ENABLED_SECTIONS = 11 | 12 | # Resources 13 | OUTPUT_DIRECTORY = 14 | INPUT = @Meta_SOURCE_DIR@/include \ 15 | @Meta_SOURCE_DIR@/doc/index.md \ 16 | @Meta_SOURCE_DIR@/example/examples.hpp 17 | FILE_PATTERNS = *.hpp *.md 18 | RECURSIVE = YES 19 | EXCLUDE = 20 | EXCLUDE_SYMBOLS = detail 21 | EXAMPLE_PATH = @Meta_SOURCE_DIR@/example \ 22 | @Meta_SOURCE_DIR@/test 23 | EXAMPLE_RECURSIVE = YES 24 | EXAMPLE_PATTERNS = *.cpp 25 | IMAGE_PATH = 26 | WARN_IF_UNDOCUMENTED = NO 27 | 28 | SHOW_GROUPED_MEMB_INC = YES 29 | BRIEF_MEMBER_DESC = YES 30 | REPEAT_BRIEF = YES 31 | ALWAYS_DETAILED_SEC = NO 32 | INLINE_INHERITED_MEMB = NO 33 | JAVADOC_AUTOBRIEF = YES 34 | QT_AUTOBRIEF = YES 35 | MULTILINE_CPP_IS_BRIEF = YES 36 | INHERIT_DOCS = NO 37 | SEPARATE_MEMBER_PAGES = NO 38 | DISTRIBUTE_GROUP_DOC = YES 39 | SUBGROUPING = NO 40 | INLINE_GROUPED_CLASSES = NO 41 | INLINE_SIMPLE_STRUCTS = NO 42 | TYPEDEF_HIDES_STRUCT = YES 43 | 44 | # Generated formats 45 | GENERATE_HTML = YES 46 | GENERATE_LATEX = NO 47 | 48 | GENERATE_TODOLIST = YES 49 | GENERATE_TESTLIST = YES 50 | GENERATE_BUGLIST = YES 51 | GENERATE_DEPRECATEDLIST = YES 52 | SHOW_USED_FILES = NO 53 | SHOW_FILES = YES 54 | SHOW_NAMESPACES = YES 55 | LAYOUT_FILE = @Meta_SOURCE_DIR@/doc/layout.xml 56 | 57 | 58 | CLASS_DIAGRAMS = YES 59 | HAVE_DOT = NO 60 | 61 | HIDE_UNDOC_RELATIONS = NO 62 | HIDE_UNDOC_MEMBERS = YES 63 | HIDE_UNDOC_CLASSES = YES 64 | HIDE_FRIEND_COMPOUNDS = NO 65 | HIDE_IN_BODY_DOCS = NO 66 | INTERNAL_DOCS = NO 67 | HIDE_SCOPE_NAMES = NO 68 | SHOW_INCLUDE_FILES = NO 69 | FORCE_LOCAL_INCLUDES = NO 70 | INLINE_INFO = NO 71 | SORT_MEMBER_DOCS = YES 72 | SORT_BRIEF_DOCS = YES 73 | SORT_MEMBERS_CTORS_1ST = NO 74 | SORT_GROUP_NAMES = YES 75 | SORT_BY_SCOPE_NAME = YES 76 | 77 | 78 | ALPHABETICAL_INDEX = NO 79 | COLS_IN_ALPHA_INDEX = 1 80 | 81 | # Preprocessing 82 | ENABLE_PREPROCESSING = YES 83 | MACRO_EXPANSION = YES 84 | EXPAND_ONLY_PREDEF = NO 85 | SEARCH_INCLUDES = YES 86 | INCLUDE_PATH = @Meta_SOURCE_DIR@/include 87 | INCLUDE_FILE_PATTERNS = 88 | PREDEFINED = META_DOXYGEN_INVOKED 89 | SKIP_FUNCTION_MACROS = NO 90 | 91 | # Source browsing 92 | SOURCE_BROWSER = YES 93 | INLINE_SOURCES = NO 94 | STRIP_CODE_COMMENTS = YES 95 | REFERENCED_BY_RELATION = YES 96 | REFERENCES_RELATION = YES 97 | REFERENCES_LINK_SOURCE = YES 98 | USE_HTAGS = NO 99 | VERBATIM_HEADERS = NO 100 | #CLANG_ASSISTED_PARSING = YES 101 | #CLANG_OPTIONS = -std=c++1y 102 | 103 | # HTML output 104 | HTML_OUTPUT = html 105 | HTML_FILE_EXTENSION = .html 106 | HTML_HEADER = 107 | HTML_FOOTER = 108 | HTML_EXTRA_STYLESHEET = 109 | HTML_EXTRA_FILES = 110 | HTML_COLORSTYLE_HUE = 75 # 0 - 359 111 | HTML_COLORSTYLE_SAT = 100 # 0 - 255 112 | HTML_COLORSTYLE_GAMMA = 80 113 | HTML_TIMESTAMP = NO 114 | HTML_DYNAMIC_SECTIONS = YES 115 | HTML_INDEX_NUM_ENTRIES = 0 # Fully expand trees in the Indexes by default 116 | DISABLE_INDEX = YES 117 | GENERATE_TREEVIEW = YES 118 | TREEVIEW_WIDTH = 270 119 | EXT_LINKS_IN_WINDOW = NO 120 | FORMULA_FONTSIZE = 10 121 | FORMULA_TRANSPARENT = YES 122 | SEARCHENGINE = YES 123 | 124 | # Mathjax (HTML only) 125 | USE_MATHJAX = NO 126 | MATHJAX_FORMAT = HTML-CSS 127 | MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest 128 | MATHJAX_EXTENSIONS = TeX/AMSmath TeX/AMSsymbols 129 | MATHJAX_CODEFILE = 130 | 131 | # Misc 132 | CREATE_SUBDIRS = NO 133 | SHORT_NAMES = NO 134 | CASE_SENSE_NAMES = YES 135 | QUIET = YES 136 | WARNINGS = YES 137 | WARN_IF_DOC_ERROR = YES 138 | 139 | -------------------------------------------------------------------------------- /test/simple_test.hpp: -------------------------------------------------------------------------------- 1 | // Range v3 library 2 | // 3 | // Copyright Eric Niebler 2014-2015 4 | // 5 | // Use, modification and distribution is subject to the 6 | // Boost Software License, Version 1.0. (See accompanying 7 | // file LICENSE_1_0.txt or copy at 8 | // http://www.boost.org/LICENSE_1_0.txt) 9 | 10 | #ifndef RANGES_SIMPLE_TEST_HPP 11 | #define RANGES_SIMPLE_TEST_HPP 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | namespace test_impl 19 | { 20 | inline int &test_failures() 21 | { 22 | static int test_failures = 0; 23 | return test_failures; 24 | } 25 | 26 | template 27 | struct streamable_base 28 | { 29 | }; 30 | 31 | template 32 | std::ostream &operator<<(std::ostream &sout, streamable_base const &) 33 | { 34 | return sout << ""; 35 | } 36 | 37 | template 38 | struct streamable : streamable_base 39 | { 40 | private: 41 | T const &t_; 42 | 43 | public: 44 | explicit streamable(T const &t) : t_(t) {} 45 | template 46 | friend auto operator<<(std::ostream &sout, 47 | streamable const &s) -> decltype(sout << std::declval()) 48 | { 49 | return sout << s.t_; 50 | } 51 | }; 52 | 53 | template 54 | streamable stream(T const &t) 55 | { 56 | return streamable{t}; 57 | } 58 | 59 | template 60 | struct R 61 | { 62 | private: 63 | char const *filename_; 64 | int lineno_; 65 | char const *expr_; 66 | T t_; 67 | bool dismissed_ = false; 68 | 69 | template 70 | void oops(U const &u) const 71 | { 72 | std::cerr << "> ERROR: CHECK failed \"" << expr_ << "\"\n" 73 | << "> \t" << filename_ << '(' << lineno_ << ')' << '\n'; 74 | if(dismissed_) 75 | std::cerr << "> \tEXPECTED: " << stream(u) << "\n> \tACTUAL: " << stream(t_) 76 | << '\n'; 77 | ++test_failures(); 78 | } 79 | void dismiss() { dismissed_ = true; } 80 | template 81 | auto eval_(int) -> decltype(!std::declval()) 82 | { 83 | return !t_; 84 | } 85 | bool eval_(long) { return true; } 86 | 87 | public: 88 | R(char const *filename, int lineno, char const *expr, T &&t) 89 | : filename_(filename), lineno_(lineno), expr_(expr), t_(std::forward(t)) 90 | { 91 | } 92 | ~R() 93 | { 94 | if(!dismissed_ && eval_(42)) 95 | this->oops(42); 96 | } 97 | template 98 | void operator==(U const &u) 99 | { 100 | dismiss(); 101 | if(!(t_ == u)) 102 | this->oops(u); 103 | } 104 | template 105 | void operator!=(U const &u) 106 | { 107 | dismiss(); 108 | if(!(t_ != u)) 109 | this->oops(u); 110 | } 111 | template 112 | void operator<(U const &u) 113 | { 114 | dismiss(); 115 | if(!(t_ < u)) 116 | this->oops(u); 117 | } 118 | template 119 | void operator<=(U const &u) 120 | { 121 | dismiss(); 122 | if(!(t_ <= u)) 123 | this->oops(u); 124 | } 125 | template 126 | void operator>(U const &u) 127 | { 128 | dismiss(); 129 | if(!(t_ > u)) 130 | this->oops(u); 131 | } 132 | template 133 | void operator>=(U const &u) 134 | { 135 | dismiss(); 136 | if(!(t_ >= u)) 137 | this->oops(u); 138 | } 139 | }; 140 | 141 | struct S 142 | { 143 | private: 144 | char const *filename_; 145 | int lineno_; 146 | char const *expr_; 147 | 148 | public: 149 | S(char const *filename, int lineno, char const *expr) 150 | : filename_(filename), lineno_(lineno), expr_(expr) 151 | { 152 | } 153 | template 154 | R operator->*(T &&t) 155 | { 156 | return {filename_, lineno_, expr_, std::forward(t)}; 157 | } 158 | }; 159 | } 160 | 161 | inline int test_result() 162 | { 163 | return ::test_impl::test_failures() ? EXIT_FAILURE : EXIT_SUCCESS; 164 | } 165 | 166 | #define CHECK(...) (void)(::test_impl::S{__FILE__, __LINE__, #__VA_ARGS__}->*__VA_ARGS__) /**/ 167 | 168 | #endif 169 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Copyright (c) 2013 GitHub, Inc. 2 | ## 3 | ## Permission is hereby granted, free of charge, to any person obtaining a 4 | ## copy of this software and associated documentation files (the "Software"), 5 | ## to deal in the Software without restriction, including without limitation 6 | ## the rights to use, copy, modify, merge, publish, distribute, sublicense, 7 | ## and/or sell copies of the Software, and to permit persons to whom the 8 | ## Software is furnished to do so, subject to the following conditions: 9 | ## 10 | ## The above copyright notice and this permission notice shall be included in 11 | ## all copies or substantial portions of the Software. 12 | ## 13 | ## THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | ## IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | ## FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | ## AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | ## LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | ## FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | ## DEALINGS IN THE SOFTWARE. 20 | 21 | # Compiled Object files 22 | *.slo 23 | *.lo 24 | *.o 25 | *.obj 26 | 27 | # Compiled Dynamic libraries 28 | *.so 29 | *.dylib 30 | *.dll 31 | 32 | # Compiled Static libraries 33 | *.lai 34 | *.la 35 | *.a 36 | *.lib 37 | 38 | # Executables 39 | *.exe 40 | *.out 41 | *.app 42 | 43 | ## Ignore Visual Studio temporary files, build results, and 44 | ## files generated by popular Visual Studio add-ons. 45 | .vscode/ 46 | 47 | # User-specific files 48 | *.suo 49 | *.user 50 | *.sln.docstates 51 | 52 | # Build results 53 | [Dd]ebug/ 54 | [Dd]ebugPublic/ 55 | [Rr]elease/ 56 | x64/ 57 | build/ 58 | bld/ 59 | [Bb]in/ 60 | [Oo]bj/ 61 | 62 | # Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets 63 | !packages/*/build/ 64 | 65 | # MSTest test Results 66 | [Tt]est[Rr]esult*/ 67 | [Bb]uild[Ll]og.* 68 | 69 | #NUNIT 70 | *.VisualState.xml 71 | TestResult.xml 72 | 73 | *_i.c 74 | *_p.c 75 | *_i.h 76 | *.ilk 77 | *.meta 78 | *.obj 79 | *.pch 80 | *.pdb 81 | *.pgc 82 | *.pgd 83 | *.rsp 84 | *.sbr 85 | *.tlb 86 | *.tli 87 | *.tlh 88 | *.tmp 89 | *.tmp_proj 90 | *.log 91 | *.vspscc 92 | *.vssscc 93 | .builds 94 | *.pidb 95 | *.svclog 96 | *.scc 97 | 98 | # Visual C++ cache files 99 | ipch/ 100 | *.aps 101 | *.ncb 102 | *.opensdf 103 | *.sdf 104 | *.cachefile 105 | 106 | # Visual Studio profiler 107 | *.psess 108 | *.vsp 109 | *.vspx 110 | 111 | # TFS 2012 Local Workspace 112 | $tf/ 113 | 114 | # Guidance Automation Toolkit 115 | *.gpState 116 | 117 | # ReSharper is a .NET coding add-in 118 | _ReSharper*/ 119 | *.[Rr]e[Ss]harper 120 | *.DotSettings.user 121 | 122 | # JustCode is a .NET coding addin-in 123 | .JustCode 124 | 125 | # TeamCity is a build add-in 126 | _TeamCity* 127 | 128 | # DotCover is a Code Coverage Tool 129 | *.dotCover 130 | 131 | # NCrunch 132 | *.ncrunch* 133 | _NCrunch_* 134 | .*crunch*.local.xml 135 | 136 | # MightyMoose 137 | *.mm.* 138 | AutoTest.Net/ 139 | 140 | # Installshield output folder 141 | [Ee]xpress/ 142 | 143 | # DocProject is a documentation generator add-in 144 | DocProject/buildhelp/ 145 | DocProject/Help/*.HxT 146 | DocProject/Help/*.HxC 147 | DocProject/Help/*.hhc 148 | DocProject/Help/*.hhk 149 | DocProject/Help/*.hhp 150 | DocProject/Help/Html2 151 | DocProject/Help/html 152 | 153 | # Click-Once directory 154 | publish/ 155 | 156 | # Publish Web Output 157 | *.Publish.xml 158 | *.azurePubxml 159 | 160 | # NuGet Packages Directory 161 | ## TODO: If you have NuGet Package Restore enabled, uncomment the next line 162 | #packages/ 163 | ## TODO: If the tool you use requires repositories.config, also uncomment the next line 164 | #!packages/repositories.config 165 | 166 | # Windows Azure Build Output 167 | csx/ 168 | *.build.csdef 169 | 170 | # Windows Store app package directory 171 | AppPackages/ 172 | 173 | # Others 174 | sql/ 175 | *.Cache 176 | ClientBin/ 177 | [Ss]tyle[Cc]op.* 178 | ~$* 179 | *~ 180 | *.dbmdl 181 | *.dbproj.schemaview 182 | *.[Pp]ublish.xml 183 | *.pfx 184 | *.publishsettings 185 | 186 | # RIA/Silverlight projects 187 | Generated_Code/ 188 | 189 | # Backup & report files from converting an old project file to a newer 190 | # Visual Studio version. Backup files are not needed, because we have git ;-) 191 | _UpgradeReport_Files/ 192 | Backup*/ 193 | UpgradeLog*.XML 194 | UpgradeLog*.htm 195 | 196 | # SQL Server files 197 | App_Data/*.mdf 198 | App_Data/*.ldf 199 | 200 | # Business Intelligence projects 201 | *.rdl.data 202 | *.bim.layout 203 | *.bim_*.settings 204 | 205 | # Microsoft Fakes 206 | FakesAssemblies/ 207 | 208 | # BiiCode 209 | bii/ 210 | 211 | # ========================= 212 | # Windows detritus 213 | # ========================= 214 | 215 | # Windows image file caches 216 | Thumbs.db 217 | ehthumbs.db 218 | 219 | # Folder config file 220 | Desktop.ini 221 | 222 | # Recycle Bin used on file shares 223 | $RECYCLE.BIN/ 224 | -------------------------------------------------------------------------------- /example/tuple_cat.cpp: -------------------------------------------------------------------------------- 1 | /// \file tuple_cat.cpp Example implementation of tuple cat using meta 2 | /// 3 | /// Meta: a tiny metaprogramming library 4 | /// 5 | /// Copyright Eric Niebler 2013-2015 6 | /// 7 | /// Use, modification and distribution is subject to the 8 | /// Boost Software License, Version 1.0. (See accompanying 9 | /// file LICENSE_1_0.txt or copy at 10 | /// http://www.boost.org/LICENSE_1_0.txt) 11 | /// 12 | /// Project home: https://github.com/ericniebler/meta 13 | /// 14 | /// Acknowledgements: Thanks Stephan T. Lavavej for spreading the word about 15 | /// tuple_cat, and the idea of bundling the tuples into a 16 | /// tuple of tuples and then using 2-dimensional indexing. 17 | /// He also discovered a bug in the implementation when 18 | /// using tuple_cat to concatenate temporary tuples 19 | /// including move-only types. 20 | #include 21 | #include 22 | #include 23 | 24 | using namespace meta; 25 | 26 | // Tuple cat is a function that takes N tuples and glues them together into one. 27 | // 28 | // The main idea behind the implementation is to take all the tuples and build 29 | // them up into a tuple of tuples. Since tuples are random-access, we can index 30 | // into this 2-dimensional array of tuples with (i,j) coordinates, where i is 31 | // the tuple index, and j the index of an element within the tuple i. 32 | 33 | // This helper function takes a tuple of tuples (Tuples), a list of tuple 34 | // indices (Is), a list of tuple element indices (Js), and the type of the 35 | // tuple to be returned. 36 | template 37 | Ret tuple_cat_helper(list, list, Tuples &&tpls) 38 | { 39 | // Note that for each element in a tuple we have a coordinate pair (i, j), 40 | // that is, the length of the lists containing the Is and the Js must be 41 | // equal: 42 | static_assert(sizeof...(Is) == sizeof...(Js), ""); 43 | // It then explodes the tuple of tuples into the return type using the 44 | // coordinates (i, j) for each element: 45 | return Ret{std::get(std::get(std::forward(tpls)))...}; 46 | } 47 | 48 | // Now we can implement tuple cat as follows: 49 | // - first we compute the inner indices (the i's), that is, to which tuple each 50 | // element belongs, 51 | // - then we compute the outer indices (the j's), that is, the position of each 52 | // element within their respective tuple 53 | template , list<...>, ... Concatenating the lists 56 | // into a single list, and returning a tuple of the list elements. 57 | typename Res = apply, concat...>>> 58 | Res tuple_cat(Tuples &&... tpls) 59 | { 60 | // With sizeof we compute the # of tuples to concatenate: 61 | static constexpr std::size_t N = sizeof...(Tuples); 62 | 63 | // To compute the inner indices: 64 | // 65 | // - First, we make a list containing one list 66 | // with the elements of each tuple: 67 | using list_of_lists_of_tuple_elements = list...>; 68 | // that is, for 3 tuples: 69 | // - tuple0, 70 | // - tuple1, and 71 | // - tuple2, 72 | // we have: list, list, list. 73 | // 74 | // - Then, we create for each tuple, a Callable that, when called with 75 | // any type, returns the tuple index. That is, we make an index sequence 76 | // from [0, N), e.g., [0, 1, 2], and transform it with the Callable 77 | // id, such that we get a list of Callables: 78 | // [always0, always1, always2]. 79 | using always_tuple_index = transform>, quote>; 80 | // 81 | // - Afterwards, we transform(list_of_tuples, always_tuple_indices, 82 | // transform): 83 | // That is, for each list of tuple elements, e.g., list, 84 | // we call transform again with a Callable, that no matter what type 85 | // is passed, returns the tuple index: 86 | // transform(list, always0) 87 | // -> list 88 | // -> list<0, 0> 89 | // For the next tuples we get a list<1>, and list<2, 2>. 90 | // This returns a list of lists of inner indices: 91 | using list_of_list_of_inner_indices = 92 | transform>; 93 | // That is, listlist<0, 0>, list<1>, list<2,2>> 94 | // 95 | // - Finally: we flatten the list, and get the list of inner indices: 96 | using inner = join; // e.g. [0, 0, 1, 2, 2] 97 | 98 | // To compute the outer indices: 99 | // 100 | // - Create a list of lists of tuple elements as above 101 | // 102 | // - For each lists, replace the list with a list of [0, size(list)) for 103 | // each list. This is done by calling transform on the list of lists of 104 | // tuple elements, with a Callable that gets the list size, makes an 105 | // index sequence, and returns that as a list: 106 | // f(list) = as_list(make_index_sequence(size(list))); 107 | // This produces list, list<0>, list<0, 1>>: 108 | // - Finally, we flatten the result: list<0, 1, 0, 0, 1>. 109 | using outer = join< // flatten: 110 | // replace list of list of tuple elements, with list of indices for each 111 | // tuple: 112 | transform...>, 113 | // f(list) = as_list(make_index_sequence(size(list))); 114 | compose, quote_i, quote>>>; 115 | return tuple_cat_helper(inner{}, outer{}, 116 | std::forward_as_tuple(std::forward(tpls)...)); 117 | } 118 | 119 | int main() 120 | { 121 | std::tuple t1; 122 | std::tuple<> t2; 123 | std::tuple t3; 124 | std::tuple t4; 125 | auto x = ::tuple_cat(t1, t2, t3, t4, std::make_tuple(std::unique_ptr{})); 126 | using expected_type = std::tuple>; 128 | static_assert(std::is_same::value, ""); 129 | } 130 | -------------------------------------------------------------------------------- /doc/layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 10 | 11 | 12 | 13 | 14 | 19 | 20 | 25 | 26 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | -------------------------------------------------------------------------------- /example/tutorial_snippets.cpp: -------------------------------------------------------------------------------- 1 | /// \file trait.cpp Code snippets for the tutorial 2 | /// 3 | /// Meta: a tiny metaprogramming library 4 | /// 5 | /// Copyright Eric Niebler 2013-2015 6 | /// 7 | /// Use, modification and distribution is subject to the 8 | /// Boost Software License, Version 1.0. (See accompanying 9 | /// file LICENSE_1_0.txt or copy at 10 | /// http://www.boost.org/LICENSE_1_0.txt) 11 | /// 12 | /// Project home: https://github.com/ericniebler/meta 13 | /// 14 | #include 15 | #include 16 | #include 17 | 18 | namespace trait0 19 | { 20 | /// [trait0] 21 | template 22 | struct t 23 | { 24 | using type = void; 25 | }; 26 | using result = typename t::type; 27 | static_assert(std::is_same{}, ""); 28 | /// [trait0] 29 | } 30 | 31 | using trait0::t; 32 | 33 | namespace trait1 34 | { 35 | /// [trait1] 36 | template 37 | using t_t = typename t::type; 38 | using result = t_t; 39 | static_assert(std::is_same{}, ""); 40 | /// [trait1] 41 | } 42 | 43 | using trait1::t_t; 44 | 45 | namespace trait2 46 | { 47 | /// [trait2] 48 | template 49 | using t2_t = meta::_t>; 50 | using result = t2_t; 51 | static_assert(std::is_same{}, ""); 52 | /// [trait2] 53 | } 54 | 55 | namespace callable0 56 | { 57 | /// [callable0] 58 | struct ac 59 | { 60 | template 61 | using invoke = void; 62 | }; 63 | /// [callable0] 64 | 65 | /// [callable1] 66 | using result = meta::invoke; 67 | static_assert(std::is_same{}, ""); 68 | /// [callable1] 69 | } 70 | 71 | namespace callable1 72 | { 73 | /// [callable2] 74 | using t_callable0 = meta::quote; 75 | using result0 = meta::invoke; 76 | static_assert(std::is_same>{}, ""); 77 | static_assert(std::is_same, void>{}, ""); 78 | 79 | using t_callable1 = meta::quote; 80 | using result1 = meta::invoke; 81 | static_assert(std::is_same{}, ""); 82 | /// [callable2] 83 | } 84 | 85 | namespace callable2 86 | { 87 | /// [callable3] 88 | using t_callable0 = meta::quote_trait; 89 | using result0 = meta::invoke; 90 | static_assert(std::is_same{}, ""); 91 | 92 | #if __cplusplus > 201103L 93 | using t_callable1 = meta::quote; 94 | using result1 = meta::invoke; 95 | static_assert(std::is_same{}, ""); 96 | #endif 97 | /// [callable3] 98 | } 99 | 100 | namespace partial_application0 101 | { 102 | /// [partial_application0] 103 | using is_float = meta::bind_front, float>; 104 | static_assert(meta::invoke{}, ""); 105 | static_assert(!meta::invoke{}, ""); 106 | 107 | using is_float2 = meta::bind_back, float>; 108 | static_assert(meta::invoke{}, ""); 109 | static_assert(!meta::invoke{}, ""); 110 | /// [partial_application0] 111 | } // namespace partial_application0 112 | 113 | namespace logical_operations0 114 | { 115 | /// [logical_operations0] 116 | using t0 = meta::if_, meta::bool_, meta::bool_>; 117 | static_assert(!t0{}, ""); 118 | 119 | using t1 = meta::and_, meta::bool_, meta::bool_>; 120 | static_assert(!t1{}, ""); 121 | 122 | using t2 = meta::or_, meta::bool_, meta::bool_>; 123 | static_assert(t2{}, ""); 124 | 125 | using t3 = meta::not_; 126 | static_assert(t3{}, ""); 127 | /// [logical_operations0] 128 | } // namespace logical_operations0 129 | 130 | namespace lambda0 131 | { 132 | /// [lambda0] 133 | using namespace meta::placeholders; 134 | using greater = meta::lambda<_a, _b, meta::lazy::less<_b, _a>>; 135 | 136 | static_assert(meta::invoke, meta::size_t<1>>{}, ""); 137 | /// [lambda0] 138 | } 139 | 140 | namespace type_list0 141 | { 142 | /// [type_list0] 143 | using list = meta::list; 144 | static_assert(list::size() == 3, ""); 145 | 146 | using front = meta::front; 147 | static_assert(std::is_same{}, ""); 148 | 149 | using back = meta::back; 150 | static_assert(std::is_same{}, ""); 151 | 152 | using at_1 = meta::at_c; 153 | 154 | static_assert(std::is_same{}, ""); 155 | 156 | using index_double = meta::find_index; 157 | static_assert(index_double{} == 1, ""); 158 | 159 | using index_char = meta::find_index; 160 | static_assert(index_char{} == meta::npos(), ""); 161 | 162 | static_assert(!meta::empty{}, ""); 163 | /// [type_list0] 164 | } 165 | 166 | namespace type_list1 167 | { 168 | using list = type_list0::list; 169 | /// [type_list1] 170 | using i = meta::size_t<1>; 171 | using at_1 = meta::at; 172 | static_assert(std::is_same{}, ""); 173 | /// [type_list1] 174 | } 175 | 176 | namespace type_list2 177 | { 178 | using list = type_list0::list; 179 | /// [type_list2] 180 | using l2 = meta::push_front; 181 | static_assert(std::is_same>{}, ""); 182 | 183 | using l3 = meta::pop_front; // equivalent to meta::drop; 184 | static_assert(std::is_same{}, ""); 185 | 186 | using l4 = meta::push_back; 187 | static_assert(std::is_same>{}, ""); 188 | 189 | using l5 = meta::drop_c; 190 | static_assert(std::is_same>{}, ""); 191 | /// [type_list2] 192 | } // namespace type_list2 193 | 194 | namespace type_list3 195 | { 196 | /// [type_list3] 197 | using list0 = meta::list; 198 | using list1 = meta::list<>; 199 | using list2 = meta::list; 200 | 201 | using concatenated = meta::concat; 202 | static_assert(std::is_same>{}, ""); 203 | 204 | using list_of_lists = meta::list; 205 | using flattened = meta::join; 206 | static_assert(std::is_same>{}, ""); 207 | 208 | using list_of_lists_of_same_length = meta::list; 209 | using zipped = meta::zip; 210 | static_assert( 211 | std::is_same, meta::list>>{}, ""); 212 | /// [type_list3] 213 | } 214 | 215 | namespace type_list4 216 | { 217 | using namespace meta::placeholders; 218 | 219 | /// [type_list4] 220 | using namespace meta::lazy; 221 | using l = meta::list; 222 | 223 | using size_of_largest_type = 224 | meta::fold, meta::lambda<_a, _b, max<_a, sizeof_<_b>>>>; 225 | static_assert(size_of_largest_type{} == meta::sizeof_{}, ""); 226 | 227 | using largest_type = 228 | meta::fold, sizeof_<_b>>, _a, _b>>>; 230 | static_assert(std::is_same{}, ""); 231 | 232 | using first_type_larger_than_char = 233 | meta::front, sizeof_>>>>; 234 | static_assert(std::is_same{}, ""); 235 | 236 | using unique_types = meta::unique; 237 | static_assert(std::is_same>{}, ""); 238 | /// [type_list4] 239 | } // namespace type_list4 240 | 241 | namespace type_list5 242 | { 243 | /// [type_list5] 244 | using t = std::tuple; 245 | using l = meta::as_list; 246 | static_assert(std::is_same>{}, ""); 247 | 248 | using i = meta::make_index_sequence<3>; 249 | using il = meta::as_list; 250 | static_assert(std::is_same, 251 | std::integral_constant, 252 | std::integral_constant>>{}, 253 | ""); 254 | /// [type_list5] 255 | } 256 | 257 | namespace composition0 258 | { 259 | /// [composition0] 260 | template 261 | using t0 = meta::_t>; 262 | template 263 | using t1 = meta::_t>; 264 | template 265 | using t2 = meta::_t>; 266 | 267 | using t = meta::compose, meta::quote, meta::quote>; 268 | static_assert(std::is_same, int const &>{}, ""); 269 | /// [composition0] 270 | } 271 | 272 | int main() 273 | { 274 | return 0; 275 | } 276 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # Copyright Louis Dionne 2013-2016 2 | # Copyright Gonzalo BG 2014-2016 3 | # Copyright Julian Becker 2015 4 | # Copyright Manu Sánchez 2015 5 | # Copyright Casey Carter 2015-2016 6 | # Copyright Eric Niebler 2015-2016 7 | # Copyright Paul Fultz II 2015-2016 8 | 9 | # Distributed under the Boost Software License, Version 1.0. 10 | # (See accompanying file LICENSE.txt or copy at http://boost.org/LICENSE_1_0.txt) 11 | 12 | # Adapted from various sources, including: 13 | # - Louis Dionne's Hana: https://github.com/ldionne/hana 14 | # - Paul Fultz II's FIT: https://github.com/pfultz2/Fit 15 | language: cpp 16 | sudo: required 17 | script: cmake 18 | 19 | git: 20 | depth: 1 21 | 22 | env: 23 | global: 24 | - DEPS_DIR=${TRAVIS_BUILD_DIR}/deps 25 | - CMAKE_VERSION="3.6.3" 26 | 27 | cache: 28 | directories: 29 | - ${DEPS_DIR}/cmake-${CMAKE_VERSION} 30 | 31 | matrix: 32 | include: 33 | - env: BUILD_TYPE=Release CPP=11 34 | os: osx 35 | compiler: clang 36 | 37 | # clang 3.6 C++11/14 Release libc++ 38 | - env: CLANG_VERSION=3.6 BUILD_TYPE=Release CPP=11 LIBCXX=On 39 | os: linux 40 | addons: &clang36 41 | apt: 42 | packages: 43 | - clang-3.6 44 | - libstdc++-5-dev 45 | sources: 46 | - ubuntu-toolchain-r-test 47 | 48 | - env: CLANG_VERSION=3.6 BUILD_TYPE=Release CPP=14 LIBCXX=On 49 | os: linux 50 | addons: *clang36 51 | 52 | # clang 3.7 C++11/14 Release libc++ 53 | - env: CLANG_VERSION=3.7 BUILD_TYPE=Release CPP=11 LIBCXX=On 54 | os: linux 55 | addons: &clang37 56 | apt: 57 | packages: 58 | - util-linux 59 | - clang-3.7 60 | - libstdc++-5-dev 61 | sources: 62 | - ubuntu-toolchain-r-test 63 | - llvm-toolchain-trusty-3.7 64 | - sourceline: 'deb http://apt.llvm.org/trusty/ llvm-toolchain-trusty-3.7 main' 65 | key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key' 66 | 67 | - env: CLANG_VERSION=3.7 BUILD_TYPE=Release CPP=14 LIBCXX=On 68 | os: linux 69 | addons: *clang37 70 | 71 | # clang 3.8 C++11/14 Release libc++ 72 | - env: CLANG_VERSION=3.8 BUILD_TYPE=Release CPP=11 LIBCXX=On 73 | os: linux 74 | addons: &clang38 75 | apt: 76 | packages: 77 | - util-linux 78 | - clang-3.8 79 | - libstdc++-5-dev 80 | sources: 81 | - ubuntu-toolchain-r-test 82 | 83 | - env: CLANG_VERSION=3.8 BUILD_TYPE=Release CPP=14 LIBCXX=On 84 | os: linux 85 | addons: *clang38 86 | 87 | # clang 3.9 C++11/14 Release libc++ 88 | - env: CLANG_VERSION=3.9 BUILD_TYPE=Release CPP=11 LIBCXX=On 89 | os: linux 90 | addons: &clang39 91 | apt: 92 | packages: 93 | - util-linux 94 | - clang-3.9 95 | - libstdc++-6-dev 96 | sources: 97 | - ubuntu-toolchain-r-test 98 | 99 | - env: CLANG_VERSION=3.9 BUILD_TYPE=Release CPP=14 LIBCXX=On 100 | os: linux 101 | addons: *clang39 102 | 103 | # clang 5 C++11/14/1z Debug/Release libc++, 11 Debug libstdc++ 104 | - env: CLANG_VERSION=5.0 BUILD_TYPE=Debug CPP=11 LIBCXX=On 105 | os: linux 106 | addons: &clang5 107 | apt: 108 | packages: 109 | - util-linux 110 | - clang-5.0 111 | - libstdc++-6-dev 112 | sources: 113 | - ubuntu-toolchain-r-test 114 | - llvm-toolchain-trusty-5.0 115 | - sourceline: 'deb http://apt.llvm.org/trusty/ llvm-toolchain-trusty-5.0 main' 116 | key_url: 'https://apt.llvm.org/llvm-snapshot.gpg.key' 117 | 118 | - env: CLANG_VERSION=5.0 BUILD_TYPE=Release CPP=11 LIBCXX=On 119 | os: linux 120 | addons: *clang5 121 | 122 | - env: CLANG_VERSION=5.0 BUILD_TYPE=Debug CPP=14 LIBCXX=On 123 | os: linux 124 | addons: *clang5 125 | 126 | - env: CLANG_VERSION=5.0 BUILD_TYPE=Release CPP=14 LIBCXX=On 127 | os: linux 128 | addons: *clang5 129 | 130 | - env: CLANG_VERSION=5.0 BUILD_TYPE=Debug CPP=1z LIBCXX=On 131 | os: linux 132 | addons: *clang5 133 | 134 | - env: CLANG_VERSION=5.0 BUILD_TYPE=Release CPP=1z LIBCXX=On 135 | os: linux 136 | addons: *clang5 137 | 138 | - env: CLANG_VERSION=5.0 BUILD_TYPE=Release CPP=11 139 | os: linux 140 | addons: *clang5 141 | 142 | # gcc-4.9 C++11/C++14 Release 143 | - env: GCC_VERSION=4.9 BUILD_TYPE=Release CPP=11 144 | os: linux 145 | addons: &gcc49 146 | apt: 147 | packages: 148 | - g++-4.9 149 | sources: 150 | - ubuntu-toolchain-r-test 151 | 152 | - env: GCC_VERSION=4.9 BUILD_TYPE=Release CPP=14 153 | os: linux 154 | addons: *gcc49 155 | 156 | # gcc-5 C++11/C++14 Release 157 | - env: GCC_VERSION=5 BUILD_TYPE=Release CPP=11 158 | os: linux 159 | addons: &gcc5 160 | apt: 161 | packages: 162 | - g++-5 163 | sources: 164 | - ubuntu-toolchain-r-test 165 | 166 | - env: GCC_VERSION=5 BUILD_TYPE=Release CPP=14 167 | os: linux 168 | addons: *gcc5 169 | 170 | # gcc-6 C++11/14/1z Release 171 | - env: GCC_VERSION=6 BUILD_TYPE=Release CPP=11 172 | os: linux 173 | addons: &gcc6 174 | apt: 175 | packages: 176 | - g++-6 177 | sources: 178 | - ubuntu-toolchain-r-test 179 | 180 | - env: GCC_VERSION=6 BUILD_TYPE=Release CPP=14 181 | os: linux 182 | addons: *gcc6 183 | 184 | - env: GCC_VERSION=6 BUILD_TYPE=Release CPP=1z 185 | os: linux 186 | addons: *gcc6 187 | 188 | # gcc-7 C++11/14/17 Release 189 | - env: GCC_VERSION=7 BUILD_TYPE=Release CPP=11 190 | os: linux 191 | addons: &gcc7 192 | apt: 193 | packages: 194 | - g++-7 195 | sources: 196 | - ubuntu-toolchain-r-test 197 | 198 | - env: GCC_VERSION=7 BUILD_TYPE=Release CPP=14 199 | os: linux 200 | addons: *gcc7 201 | 202 | - env: GCC_VERSION=7 BUILD_TYPE=Release CPP=17 203 | os: linux 204 | addons: *gcc7 205 | 206 | # gcc-8 C++11/14/17/2a Debug/Release 207 | - env: GCC_VERSION=8 BUILD_TYPE=Debug CPP=11 208 | os: linux 209 | addons: &gcc8 210 | apt: 211 | packages: 212 | - g++-8 213 | sources: 214 | - ubuntu-toolchain-r-test 215 | 216 | - env: GCC_VERSION=8 BUILD_TYPE=Release CPP=11 217 | os: linux 218 | addons: *gcc8 219 | 220 | - env: GCC_VERSION=8 BUILD_TYPE=Debug CPP=14 221 | os: linux 222 | addons: *gcc8 223 | 224 | - env: GCC_VERSION=8 BUILD_TYPE=Release CPP=14 225 | os: linux 226 | addons: *gcc8 227 | 228 | - env: GCC_VERSION=8 BUILD_TYPE=Debug CPP=17 229 | os: linux 230 | addons: *gcc8 231 | 232 | - env: GCC_VERSION=8 BUILD_TYPE=Release CPP=17 233 | os: linux 234 | addons: *gcc8 235 | 236 | - env: GCC_VERSION=8 BUILD_TYPE=Debug CPP=2a 237 | os: linux 238 | addons: *gcc8 239 | 240 | - env: GCC_VERSION=8 BUILD_TYPE=Release CPP=2a 241 | os: linux 242 | addons: *gcc8 243 | 244 | # Install dependencies 245 | before_install: 246 | - set -e 247 | - | 248 | if [ "$TRAVIS_OS_NAME" == "osx" ]; then 249 | brew update 250 | brew install gnu-sed 251 | brew install gnu-which 252 | brew upgrade cmake 253 | export PATH="/usr/local/opt/coreutils/libexec/gnubin:$PATH" 254 | fi 255 | - | 256 | if [ "${TRAVIS_OS_NAME}" == "linux" ]; then 257 | if [ -f ${DEPS_DIR}/cmake-${CMAKE_VERSION}/cached ]; then 258 | echo "Using cached cmake version ${CMAKE_VERSION}." 259 | else 260 | CMAKE_URL="https://cmake.org/files/v3.6/cmake-${CMAKE_VERSION}-Linux-x86_64.tar.gz" 261 | mkdir -p ${DEPS_DIR}/cmake-${CMAKE_VERSION} 262 | travis_retry wget --no-check-certificate --quiet -O - "${CMAKE_URL}" | tar --strip-components=1 -xz -C ${DEPS_DIR}/cmake-${CMAKE_VERSION} 263 | touch ${DEPS_DIR}/cmake-${CMAKE_VERSION}/cached 264 | fi 265 | export PATH="${DEPS_DIR}/cmake-${CMAKE_VERSION}/bin:${PATH}" 266 | fi 267 | - if [ -n "$GCC_VERSION" ]; then export CXX="g++-${GCC_VERSION}" CC="gcc-${GCC_VERSION}"; fi 268 | - if [ -n "$CLANG_VERSION" ]; then export CXX="clang++-${CLANG_VERSION}" CC="clang-${CLANG_VERSION}"; fi 269 | - which $CXX && $CXX --version 270 | - which $CC 271 | - if [ -n "$CLANG_VERSION" ]; then PATH="${PATH}" CXX="$CXX" CC="$CC" ./install_libcxx.sh; fi 272 | 273 | install: 274 | - | 275 | if [ "$LIBCXX" == "On" ]; then 276 | CXX_FLAGS="${CXX_FLAGS} -stdlib=libc++ -nostdinc++ -cxx-isystem ${TRAVIS_BUILD_DIR}/llvm/include/c++/v1/ -Wno-unused-command-line-argument" 277 | CXX_LINKER_FLAGS="${CXX_LINKER_FLAGS} -L ${TRAVIS_BUILD_DIR}/llvm/lib -Wl,-rpath,${TRAVIS_BUILD_DIR}/llvm/lib -lc++abi" 278 | fi 279 | 280 | - mkdir -p build 281 | # This cd works, but causes the shell to exit on OSX with set -e. I don't even. 282 | - set +e; cd build; set -e; pwd 283 | - cmake .. -DCMAKE_BUILD_TYPE=$BUILD_TYPE -DCMAKE_CXX_FLAGS="${CXX_FLAGS}" -DCMAKE_EXE_LINKER_FLAGS="${CXX_LINKER_FLAGS}" -DMETA_CXX_STD=$CPP -Wdev 284 | - cat CMakeFiles/CMakeError.log || true 285 | - cat CMakeFiles/CMakeOutput.log || true 286 | 287 | - make -j2 VERBOSE=1 288 | 289 | script: 290 | - ctest -j2 -VV 291 | 292 | notifications: 293 | email: false 294 | -------------------------------------------------------------------------------- /include/meta/meta_fwd.hpp: -------------------------------------------------------------------------------- 1 | /// \file meta_fwd.hpp Forward declarations 2 | // 3 | // Meta library 4 | // 5 | // Copyright Eric Niebler 2014-present 6 | // 7 | // Use, modification and distribution is subject to the 8 | // Boost Software License, Version 1.0. (See accompanying 9 | // file LICENSE_1_0.txt or copy at 10 | // http://www.boost.org/LICENSE_1_0.txt) 11 | // 12 | // Project home: https://github.com/ericniebler/meta 13 | // 14 | 15 | #ifndef META_FWD_HPP 16 | #define META_FWD_HPP 17 | 18 | #include 19 | #include 20 | 21 | #ifdef __clang__ 22 | #pragma GCC diagnostic push 23 | #pragma GCC diagnostic ignored "-Wmissing-variable-declarations" 24 | #endif 25 | 26 | #define META_CXX_STD_14 201402L 27 | #define META_CXX_STD_17 201703L 28 | 29 | #if defined(_MSVC_LANG) && _MSVC_LANG > __cplusplus // Older clangs define _MSVC_LANG < __cplusplus 30 | #define META_CXX_VER _MSVC_LANG 31 | #else 32 | #define META_CXX_VER __cplusplus 33 | #endif 34 | 35 | #if defined(__apple_build_version__) || defined(__clang__) 36 | #if defined(__apple_build_version__) || (defined(__clang__) && __clang_major__ < 6) 37 | #define META_WORKAROUND_LLVM_28385 // https://llvm.org/bugs/show_bug.cgi?id=28385 38 | #endif 39 | 40 | #elif defined(_MSC_VER) 41 | #define META_HAS_MAKE_INTEGER_SEQ 1 42 | #if _MSC_VER < 1921 43 | #define META_WORKAROUND_MSVC_756112 // fold expression + alias templates in template argument (Fixed in next VS2019 toolset update) 44 | #if _MSC_VER < 1920 45 | #define META_WORKAROUND_MSVC_702792 // Fixed in VS2019 Preview 2 46 | #define META_WORKAROUND_MSVC_703656 // Fixed in VS2019 Preview 2 47 | #endif // _MSC_VER < 1920 48 | #endif // _MSC_VER < 1921 49 | 50 | #elif defined(__GNUC__) 51 | #define META_WORKAROUND_GCC_86356 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=86356 52 | #if __GNUC__ >= 8 53 | #define META_HAS_INTEGER_PACK 1 54 | #else 55 | #define META_WORKAROUND_GCC_UNKNOWN1 // Older GCCs don't like fold + debug + -march=native 56 | #endif 57 | #if __GNUC__ == 5 && __GNUC_MINOR__ == 1 58 | #define META_WORKAROUND_GCC_66405 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66405 59 | #endif 60 | #if __GNUC__ < 5 61 | #define META_WORKAROUND_CWG_1558 // https://wg21.link/cwg1558 62 | #endif 63 | #endif 64 | 65 | #ifndef META_CXX_VARIABLE_TEMPLATES 66 | #ifdef __cpp_variable_templates 67 | #define META_CXX_VARIABLE_TEMPLATES __cpp_variable_templates 68 | #else 69 | #define META_CXX_VARIABLE_TEMPLATES (META_CXX_VER >= META_CXX_STD_14) 70 | #endif 71 | #endif 72 | 73 | #ifndef META_CXX_INLINE_VARIABLES 74 | #ifdef __cpp_inline_variables 75 | #define META_CXX_INLINE_VARIABLES __cpp_inline_variables 76 | #else 77 | #define META_CXX_INLINE_VARIABLES (META_CXX_VER >= META_CXX_STD_17) 78 | #endif 79 | #endif 80 | 81 | #ifndef META_INLINE_VAR 82 | #if META_CXX_INLINE_VARIABLES 83 | #define META_INLINE_VAR inline 84 | #else 85 | #define META_INLINE_VAR 86 | #endif 87 | #endif 88 | 89 | #ifndef META_CXX_INTEGER_SEQUENCE 90 | #ifdef __cpp_lib_integer_sequence 91 | #define META_CXX_INTEGER_SEQUENCE __cpp_lib_integer_sequence 92 | #else 93 | #define META_CXX_INTEGER_SEQUENCE (META_CXX_VER >= META_CXX_STD_14) 94 | #endif 95 | #endif 96 | 97 | #ifndef META_HAS_MAKE_INTEGER_SEQ 98 | #ifdef __has_builtin 99 | #if __has_builtin(__make_integer_seq) 100 | #define META_HAS_MAKE_INTEGER_SEQ 1 101 | #endif 102 | #endif 103 | #endif 104 | #ifndef META_HAS_MAKE_INTEGER_SEQ 105 | #define META_HAS_MAKE_INTEGER_SEQ 0 106 | #endif 107 | 108 | #ifndef META_HAS_INTEGER_PACK 109 | #define META_HAS_INTEGER_PACK 0 110 | #endif 111 | 112 | #ifndef META_HAS_TYPE_PACK_ELEMENT 113 | #ifdef __has_builtin 114 | #if __has_builtin(__type_pack_element) 115 | #define META_HAS_TYPE_PACK_ELEMENT 1 116 | #endif 117 | #endif 118 | #endif 119 | #ifndef META_HAS_TYPE_PACK_ELEMENT 120 | #define META_HAS_TYPE_PACK_ELEMENT 0 121 | #endif 122 | 123 | #if !defined(META_DEPRECATED) && !defined(META_DISABLE_DEPRECATED_WARNINGS) 124 | #if defined(__cpp_attribute_deprecated) || META_CXX_VER >= META_CXX_STD_14 125 | #define META_DEPRECATED(...) [[deprecated(__VA_ARGS__)]] 126 | #elif defined(__clang__) || defined(__GNUC__) 127 | #define META_DEPRECATED(...) __attribute__((deprecated(__VA_ARGS__))) 128 | #endif 129 | #endif 130 | #ifndef META_DEPRECATED 131 | #define META_DEPRECATED(...) 132 | #endif 133 | 134 | // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64970 135 | #if(defined(__GNUC__) && __GNUC__ >= 5) || defined(__clang__) 136 | #define META_WORKAROUND_GCC_64970 137 | #endif 138 | 139 | #ifndef META_CXX_FOLD_EXPRESSIONS 140 | #ifdef __cpp_fold_expressions 141 | #define META_CXX_FOLD_EXPRESSIONS __cpp_fold_expressions 142 | #else 143 | #define META_CXX_FOLD_EXPRESSIONS (META_CXX_VER >= META_CXX_STD_17) 144 | #endif 145 | #endif 146 | 147 | #if META_CXX_FOLD_EXPRESSIONS 148 | #if !META_CXX_VARIABLE_TEMPLATES 149 | #error Fold expressions, but no variable templates? 150 | #endif 151 | #endif 152 | 153 | #if defined(__cpp_concepts) && __cpp_concepts > 0 154 | #if !META_CXX_VARIABLE_TEMPLATES 155 | #error Concepts, but no variable templates? 156 | #endif 157 | #if __cpp_concepts <= 201507L 158 | #define META_CONCEPT concept bool 159 | // TS concepts subsumption barrier for atomic expressions 160 | #define META_CONCEPT_BARRIER(...) ::meta::detail::bool_<__VA_ARGS__> 161 | #else 162 | #define META_CONCEPT concept 163 | #define META_CONCEPT_BARRIER(...) __VA_ARGS__ 164 | #endif 165 | #define META_TYPE_CONSTRAINT(...) __VA_ARGS__ 166 | #else 167 | #define META_TYPE_CONSTRAINT(...) typename 168 | #endif 169 | 170 | namespace meta 171 | { 172 | #if META_CXX_INTEGER_SEQUENCE 173 | using std::integer_sequence; 174 | #else 175 | template 176 | struct integer_sequence; 177 | #endif 178 | 179 | template 180 | struct list; 181 | 182 | template 183 | struct id; 184 | 185 | template