diff --git a/.travis.yml b/.travis.yml index 143d82dc..5b6fd9cd 100644 --- a/.travis.yml +++ b/.travis.yml @@ -29,8 +29,13 @@ addons: - llvm-toolchain-precise-3.6 - llvm-toolchain-precise-3.7 - llvm-toolchain-precise-3.8 + - llvm-toolchain-precise-3.9 matrix: + allow_failures: + - compiler: clang++ + env: CXX_VERSION=3.9 + exclude: - env: BOGUS_JOB=true @@ -124,11 +129,13 @@ before_install: if [[ -n "${TRAVIS_TAG}" ]] then METAL_VERSION="${TRAVIS_TAG}" + METAL_VERSION_EXACT=true else METAL_VERSION=$( \ curl -Ls https://github.com/brunocodutra/metal/tags | \ awk '/tag-name/{print $3;exit}' FS='[<>]' \ ) + METAL_VERSION_EXACT=false fi - METAL_VERSION="${METAL_VERSION%%-*}" @@ -160,12 +167,8 @@ before_script: - (cd "${METAL_BUILD_PATH}" && cmake "${METAL_SOURCE_PATH}" ${CMAKE_ARGS[@]} && make install) - CMAKE_ARGS+=("-DCMAKE_PREFIX_PATH=${METAL_INSTALL_PATH}") - - | - if [[ -n "${METAL_VERSION}" ]] - then - CMAKE_ARGS+=("-DMETAL_VERSION=${METAL_VERSION}") - fi - + - CMAKE_ARGS+=("-DMETAL_VERSION=${METAL_VERSION}") + - CMAKE_ARGS+=("-DMETAL_VERSION_EXACT=${METAL_VERSION_EXACT}") - | if [[ "${BUILD_DOC}" != "true" ]] then diff --git a/CMakeLists.txt b/CMakeLists.txt index d4494301..74d28d5b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,128 +6,10 @@ cmake_minimum_required(VERSION 2.8.12) project(Metal CXX) -set(METAL_MAJOR_VERSION 0) -set(METAL_MINOR_VERSION 2) -set(METAL_PATCH_VERSION 0) -set( - METAL_VERSION - ${METAL_MAJOR_VERSION}.${METAL_MINOR_VERSION}.${METAL_PATCH_VERSION} -) - -if(WIN32 AND NOT CYGWIN) - set(METAL_CMAKE_INSTALL_DIR_DEF CMake) -else() - set(METAL_CMAKE_INSTALL_DIR_DEF lib/cmake/Metal) -endif() - -set(METAL_CMAKE_INSTALL_DIR - ${METAL_CMAKE_INSTALL_DIR_DEF} CACHE PATH - "installation directory for Metal CMake files" -) - -set(METAL_INCLUDE_INSTALL_DIR - include CACHE PATH - "installation directory for Metal header files" -) - -option(METAL_VERBOSE "increase output verbosity" OFF) -option(METAL_ENABLE_BASIC_WARNINGS "enable basic compiler warnings" OFF) -option(METAL_ENABLE_EXTRA_WARNINGS "enable extra compiler warnings" OFF) -option(METAL_STRICT "treat compiler warnings as errors" OFF) - -if(METAL_ENABLE_EXTRA_WARNINGS) - set(METAL_ENABLE_BASIC_WARNINGS ON) -endif() - -set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake") -include(metal) - -if(METAL_VERBOSE) - metal_try_add_flag(-v) - metal_try_add_flag(-ftemplate-backtrace-limit=0) - metal_try_add_flag(-fdiagnostics-show-template-tree) - metal_try_add_flag(-fno-elide-type) -endif() - -if(METAL_ENABLE_BASIC_WARNINGS) - metal_try_add_flag(-W) - metal_try_add_flag(-Wall) - metal_try_add_flag(/W3) -endif() - -if(METAL_ENABLE_EXTRA_WARNINGS) - metal_try_add_flag(-Wextra) - metal_try_add_flag(-Weverything) - metal_try_add_flag(-Wno-c++98-compat) - metal_try_add_flag(-Wno-c++98-compat-pedantic) - metal_try_add_flag(-Wno-documentation) - metal_try_add_flag(-Wno-documentation-unknown-command) - metal_try_add_flag(/W4) -endif() - -if(METAL_STRICT) - metal_try_add_flag(-pedantic-errors) - metal_try_add_flag(-Werror) - metal_try_add_flag(/Za) - metal_try_add_flag(/WX) -endif() - -foreach(dialect - -std=c++17 -std=c++1z - -std=c++14 -std=c++1y - /std:c++latest -) - metal_try_add_flag(${dialect} result) - if(${result}) - break() - endif() -endforeach() - -set(METAL_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include/) - -include_directories("${METAL_INCLUDE_DIR}") - -enable_testing() +include("${CMAKE_SOURCE_DIR}/cmake/config.cmake") +include("${CMAKE_SOURCE_DIR}/cmake/testing.cmake") +include("${CMAKE_SOURCE_DIR}/cmake/deployment.cmake") add_subdirectory(doc) add_subdirectory(example) add_subdirectory(test) - -foreach(_ INCLUDE CMAKE) - if(NOT IS_ABSOLUTE "${METAL_${_}_INSTALL_DIR}") - set( - METAL_${_}_INSTALL_DIR - "${CMAKE_INSTALL_PREFIX}/${METAL_${_}_INSTALL_DIR}" - ) - endif() -endforeach() - -file( - RELATIVE_PATH METAL_INCLUDE_DIRS_CONF - "${METAL_CMAKE_INSTALL_DIR}" "${METAL_INCLUDE_INSTALL_DIR}" -) - -set(METAL_INCLUDE_DIRS_CONF "\${METAL_CMAKE_DIR}/${METAL_INCLUDE_DIRS_CONF}") -configure_file( - cmake/MetalConfig.cmake.in - "${PROJECT_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/MetalConfig.cmake" - @ONLY -) - -configure_file( - cmake/MetalConfigVersion.cmake.in - "${PROJECT_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/MetalConfigVersion.cmake" - @ONLY -) - -install( - DIRECTORY "${METAL_INCLUDE_DIR}" - DESTINATION "${METAL_INCLUDE_INSTALL_DIR}" -) - -install( - FILES - "${PROJECT_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/MetalConfig.cmake" - "${PROJECT_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/MetalConfigVersion.cmake" - DESTINATION "${METAL_CMAKE_INSTALL_DIR}" -) diff --git a/cmake/MetalConfig.cmake.in b/cmake/MetalConfig.cmake.in index e4604699..36549d57 100644 --- a/cmake/MetalConfig.cmake.in +++ b/cmake/MetalConfig.cmake.in @@ -7,4 +7,4 @@ # METAL_INCLUDE_DIRS - include directories for Metal get_filename_component(METAL_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH) -set(METAL_INCLUDE_DIRS "@METAL_INCLUDE_DIRS_CONF@") +set(METAL_INCLUDE_DIRS "@METAL_INCLUDE_DIRS@") diff --git a/cmake/config.cmake b/cmake/config.cmake new file mode 100644 index 00000000..1c46c21c --- /dev/null +++ b/cmake/config.cmake @@ -0,0 +1,78 @@ +# Copyright Bruno Dutra 2015-2016 +# Distributed under the Boost Software License, Version 1.0. +# See accompanying file LICENSE.txt or copy at http://boost.org/LICENSE_1_0.txt + +set(METAL_INCLUDE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/include/") + +file(STRINGS "${METAL_INCLUDE_DIR}/metal/config/version.hpp" + METAL_CONFIG_VERSION_HPP REGEX "METAL_[A-Z]+ [0-9]+" LIMIT_COUNT 3 +) + +LIST(GET METAL_CONFIG_VERSION_HPP 0 METAL_MAJOR) +LIST(GET METAL_CONFIG_VERSION_HPP 1 METAL_MINOR) +LIST(GET METAL_CONFIG_VERSION_HPP 2 METAL_PATCH) + +string(REGEX REPLACE ".*MAJOR ([0-9]+).*" "\\1" METAL_MAJOR "${METAL_MAJOR}") +string(REGEX REPLACE ".*MINOR ([0-9]+).*" "\\1" METAL_MINOR "${METAL_MINOR}") +string(REGEX REPLACE ".*PATCH ([0-9]+).*" "\\1" METAL_PATCH "${METAL_PATCH}") + +set(METAL_VERSION "${METAL_MAJOR}.${METAL_MINOR}.${METAL_PATCH}") + +message(STATUS "Configuring Metal ${METAL_VERSION}") + +option(METAL_ENABLE_WARNINGS "enable compiler warnings" ON) +option(METAL_STRICT "treat compiler warnings as errors" OFF) +option(METAL_VERBOSE "increase output verbosity" OFF) + +include(CheckCXXCompilerFlag) +function(metal_try_add_flag _flag) + set(result "${_flag}") + string(TOUPPER "${result}" result) + string(REGEX REPLACE "[+]" "X" result "${result}") + string(REGEX REPLACE "[-/;=]" "_" result "${result}") + string(REGEX REPLACE "[^ A-Z_0-9]" "" result "${result}") + string(REGEX REPLACE "^[ ]*([A-Z_0-9]+) ?.*$" "\\1" result "${result}") + set(result "HAS${result}") + + check_cxx_compiler_flag(${_flag} ${result}) + if(${result}) + add_compile_options(${_flag}) + endif() + + if(ARGN) + set(${ARGN} ${result} PARENT_SCOPE) + endif() +endfunction() + +if(METAL_ENABLE_WARNINGS) + metal_try_add_flag(-W) + metal_try_add_flag(-Wall) + metal_try_add_flag(-Wextra) + metal_try_add_flag(-Weverything) + metal_try_add_flag(-Wno-c++98-compat) + metal_try_add_flag(-Wno-c++98-compat-pedantic) + metal_try_add_flag(-Wno-documentation) + metal_try_add_flag(-Wno-documentation-unknown-command) + metal_try_add_flag(/W3) +endif() + +if(METAL_STRICT) + metal_try_add_flag(-pedantic-errors) + metal_try_add_flag(-Werror) + metal_try_add_flag(/Za) + metal_try_add_flag(/WX) +endif() + +if(METAL_VERBOSE) + metal_try_add_flag(-v) + metal_try_add_flag(-ftemplate-backtrace-limit=0) + metal_try_add_flag(-fdiagnostics-show-template-tree) + metal_try_add_flag(-fno-elide-type) +endif() + +foreach(dialect -std=c++17 -std=c++1z -std=c++14 -std=c++1y /std:c++latest) + metal_try_add_flag(${dialect} result) + if(${result}) + break() + endif() +endforeach() diff --git a/cmake/deployment.cmake b/cmake/deployment.cmake new file mode 100644 index 00000000..3f4a13e7 --- /dev/null +++ b/cmake/deployment.cmake @@ -0,0 +1,52 @@ +# Copyright Bruno Dutra 2015-2016 +# Distributed under the Boost Software License, Version 1.0. +# See accompanying file LICENSE.txt or copy at http://boost.org/LICENSE_1_0.txt + +if(WIN32 AND NOT CYGWIN) + set(METAL_CMAKE_INSTALL_DIR_DEF CMake) +else() + set(METAL_CMAKE_INSTALL_DIR_DEF lib/cmake/Metal) +endif() + +set(METAL_CMAKE_INSTALL_DIR ${METAL_CMAKE_INSTALL_DIR_DEF} CACHE PATH + "installation directory for Metal CMake files" +) + +set(METAL_INCLUDE_INSTALL_DIR include CACHE PATH + "installation directory for Metal header files" +) + +foreach(_ INCLUDE CMAKE) + if(NOT IS_ABSOLUTE "${METAL_${_}_INSTALL_DIR}") + set(METAL_${_}_INSTALL_DIR + "${CMAKE_INSTALL_PREFIX}/${METAL_${_}_INSTALL_DIR}" + ) + endif() +endforeach() + +file(RELATIVE_PATH METAL_INCLUDE_DIRS + "${METAL_CMAKE_INSTALL_DIR}" "${METAL_INCLUDE_INSTALL_DIR}" +) + +set(METAL_INCLUDE_DIRS "\${METAL_CMAKE_DIR}/${METAL_INCLUDE_DIRS}") + +configure_file(cmake/MetalConfig.cmake.in + "${PROJECT_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/MetalConfig.cmake" + @ONLY +) + +configure_file(cmake/MetalConfigVersion.cmake.in + "${PROJECT_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/MetalConfigVersion.cmake" + @ONLY +) + +install(DIRECTORY + "${METAL_INCLUDE_DIR}" + DESTINATION "${METAL_INCLUDE_INSTALL_DIR}" +) + +install(FILES + "${PROJECT_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/MetalConfig.cmake" + "${PROJECT_BINARY_DIR}/${CMAKE_FILES_DIRECTORY}/MetalConfigVersion.cmake" + DESTINATION "${METAL_CMAKE_INSTALL_DIR}" +) diff --git a/cmake/metal.cmake b/cmake/testing.cmake similarity index 62% rename from cmake/metal.cmake rename to cmake/testing.cmake index 63d137c8..a084e9b1 100644 --- a/cmake/metal.cmake +++ b/cmake/testing.cmake @@ -2,28 +2,9 @@ # Distributed under the Boost Software License, Version 1.0. # See accompanying file LICENSE.txt or copy at http://boost.org/LICENSE_1_0.txt -include(CheckCXXCompilerFlag) +enable_testing() -function(metal_try_add_flag _flag) - set(result "${_flag}") - string(TOUPPER "${result}" result) - string(REGEX REPLACE "[+]" "X" result "${result}") - string(REGEX REPLACE "[-/;=]" "_" result "${result}") - string(REGEX REPLACE "[^ A-Z_0-9]" "" result "${result}") - string(REGEX REPLACE "^[ ]*([A-Z_0-9]+) ?.*$" "\\1" result "${result}") - set(result "HAS${result}") - - check_cxx_compiler_flag(${_flag} ${result}) - if(${result}) - add_compile_options(${_flag}) - endif() - - if(ARGN) - set(${ARGN} ${result} PARENT_SCOPE) - endif() -endfunction() - -function(metal_add_test_tree _root _prefix) +function(metal_build_test_tree _root _prefix) if(NOT TARGET ${_root}) message(FATAL_ERROR "'${_root}' is not a target.") endif() @@ -55,11 +36,10 @@ function(metal_add_test_tree _root _prefix) add_dependencies(${_root} ${target}) if(IS_DIRECTORY "${_prefix}/${node}") - metal_add_test_tree(${target} "${_prefix}/${node}") + metal_build_test_tree(${target} "${_prefix}/${node}") endif() - add_test( - NAME ${target} + add_test(NAME ${target} COMMAND ${CMAKE_COMMAND} --build . --target ${target} WORKING_DIRECTORY "${PROJECT_BINARY_DIR}" ) diff --git a/doc/CMakeLists.txt b/doc/CMakeLists.txt index 5ee6cf86..f2205f9f 100644 --- a/doc/CMakeLists.txt +++ b/doc/CMakeLists.txt @@ -11,7 +11,9 @@ endif() configure_file(Doxyfile.in METAL_DOXYFILE @ONLY) add_custom_target(doc - COMMAND ${CMAKE_COMMAND} -E remove_directory html + COMMAND ${CMAKE_COMMAND} -E remove_directory "html" COMMAND ${DOXYGEN_EXECUTABLE} METAL_DOXYFILE - COMMENT "building documentation..." + COMMAND ${CMAKE_COMMAND} -E remove + "html/*.png" "html/dir_*.html" "html/namespacemetal.html" + "html/dynsections.js" "html/doxygen.css" "html/tabs.css" ) diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in index 40cf283f..3e6ada9e 100644 --- a/doc/Doxyfile.in +++ b/doc/Doxyfile.in @@ -253,7 +253,7 @@ ALIASES +=semantics="\par Semantics" ALIASES +=tip{1}="
Tip
\1
" ALIASES +=note{1}="
Note
\1
" -ALIASES +=danger{1}="
Warning
\1
" +ALIASES +=warning{1}="
Warning
\1
" # This tag can be used to specify a number of word-keyword mappings (TCL only). # A mapping has the form "name=value". For example adding "class=itcl::class" @@ -500,7 +500,7 @@ HIDE_UNDOC_CLASSES = YES # included in the documentation. # The default value is: NO. -HIDE_FRIEND_COMPOUNDS = NO +HIDE_FRIEND_COMPOUNDS = YES # If the HIDE_IN_BODY_DOCS tag is set to YES, doxygen will hide any # documentation blocks found inside the body of a function. If set to NO, these @@ -543,7 +543,7 @@ HIDE_COMPOUND_REFERENCE= YES # the files that are included by a file in the documentation of that file. # The default value is: YES. -SHOW_INCLUDE_FILES = YES +SHOW_INCLUDE_FILES = NO # If the SHOW_GROUPED_MEMB_INC tag is set to YES then Doxygen will add for each # grouped member an include statement to the documentation, telling the reader @@ -589,7 +589,7 @@ SORT_BRIEF_DOCS = YES # detailed member documentation. # The default value is: NO. -SORT_MEMBERS_CTORS_1ST = NO +SORT_MEMBERS_CTORS_1ST = YES # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the hierarchy # of group names into alphabetical order. If set to NO the group names will @@ -672,7 +672,7 @@ SHOW_USED_FILES = NO # (if specified). # The default value is: YES. -SHOW_FILES = YES +SHOW_FILES = NO # Set the SHOW_NAMESPACES tag to NO to disable the generation of the Namespaces # page. This will remove the Namespaces entry from the Quick Index and from the @@ -805,7 +805,7 @@ INPUT_ENCODING = UTF-8 # *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf, # *.qsf, *.as and *.js. -FILE_PATTERNS = *.hpp *.md *.dox +FILE_PATTERNS = *.hpp *.md # The RECURSIVE tag can be used to specify whether or not subdirectories should # be searched for input files as well. @@ -853,7 +853,7 @@ EXCLUDE_SYMBOLS = detail # that contain example code fragments that are included (see the \include # command). -EXAMPLE_PATH = @Metal_SOURCE_DIR@/example +EXAMPLE_PATH = @Metal_SOURCE_DIR@/example/src # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and @@ -1007,7 +1007,7 @@ USE_HTAGS = NO # See also: Section \class. # The default value is: YES. -VERBATIM_HEADERS = YES +VERBATIM_HEADERS = NO #--------------------------------------------------------------------------- # Configuration options related to the alphabetical class index @@ -1025,7 +1025,7 @@ ALPHABETICAL_INDEX = YES # Minimum value: 1, maximum value: 20, default value: 5. # This tag requires that the tag ALPHABETICAL_INDEX is set to YES. -COLS_IN_ALPHA_INDEX = 5 +COLS_IN_ALPHA_INDEX = 1 # In case all classes in a project start with a common prefix, all classes will # be put under the same header in the alphabetical index. The IGNORE_PREFIX tag @@ -1122,15 +1122,15 @@ HTML_EXTRA_STYLESHEET = # files will be copied as-is; there are no commands or markers available. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_EXTRA_FILES = @Metal_SOURCE_DIR@/doc/css/octicons.css \ - @Metal_SOURCE_DIR@/doc/icons/octicons.eot \ +HTML_EXTRA_FILES = @Metal_SOURCE_DIR@/doc/icons/octicons.eot \ @Metal_SOURCE_DIR@/doc/icons/octicons.svg \ @Metal_SOURCE_DIR@/doc/icons/octicons.ttf \ @Metal_SOURCE_DIR@/doc/icons/octicons.woff \ - @Metal_SOURCE_DIR@/doc/js/jquery-1.11.3.min.js \ @Metal_SOURCE_DIR@/doc/css/bootstrap.min.css \ - @Metal_SOURCE_DIR@/doc/js/bootstrap.min.js \ + @Metal_SOURCE_DIR@/doc/css/octicons.css \ @Metal_SOURCE_DIR@/doc/css/metal.css \ + @Metal_SOURCE_DIR@/doc/js/bootstrap.min.js \ + @Metal_SOURCE_DIR@/doc/js/jquery.js \ @Metal_SOURCE_DIR@/doc/js/metal.js \ # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen @@ -1169,7 +1169,7 @@ HTML_COLORSTYLE_GAMMA = 101 # The default value is: YES. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_TIMESTAMP = YES +HTML_TIMESTAMP = NO # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the @@ -1190,7 +1190,7 @@ HTML_DYNAMIC_SECTIONS = NO # Minimum value: 0, maximum value: 9999, default value: 100. # This tag requires that the tag GENERATE_HTML is set to YES. -HTML_INDEX_NUM_ENTRIES = 100 +HTML_INDEX_NUM_ENTRIES = 0 # If the GENERATE_DOCSET tag is set to YES, additional index files will be # generated that can be used as input for Apple's Xcode 3 integrated development @@ -1991,14 +1991,14 @@ EXPAND_ONLY_PREDEF = NO # The default value is: YES. # This tag requires that the tag ENABLE_PREPROCESSING is set to YES. -SEARCH_INCLUDES = YES +SEARCH_INCLUDES = NO # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by the # preprocessor. # This tag requires that the tag SEARCH_INCLUDES is set to YES. -INCLUDE_PATH = @Metal_SOURCE_DIR@/include +INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the @@ -2189,7 +2189,7 @@ COLLABORATION_GRAPH = NO # The default value is: YES. # This tag requires that the tag HAVE_DOT is set to YES. -GROUP_GRAPHS = YES +GROUP_GRAPHS = NO # If the UML_LOOK tag is set to YES, doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling diff --git a/doc/css/metal.css b/doc/css/metal.css index 59fefe91..bb1e0669 100644 --- a/doc/css/metal.css +++ b/doc/css/metal.css @@ -26,12 +26,34 @@ html, body { #content { height: auto; min-height: 100%; - padding-top: 60px; - padding-bottom: 100px; - margin-bottom: -100px; + padding-top: 55px; + padding-bottom: 140px; + margin-bottom: -140px; } -#toolbar > * { +@media (max-width: 767px) { + #content { + padding-top: 110px; + } +} + +#footer { + height: 100px; + font-size: 0.9em; + text-align: center; + margin-top: 40px; + padding-top: 20px; + border-top: 1px solid #EEEEEE; +} + +.github-btn { + overflow: hidden; + border: 0px none; + height: 20px; + width: 102px; +} + +.toolbar > * { border-bottom: 1px solid #EEEEEE; } @@ -74,17 +96,18 @@ html, body { } h1:hover > a.anchor:after, -h2:hover > a.anchor:after { +h2:hover > a.anchor:after, +h3:hover > a.anchor:after { content: "ยง"; position: absolute; - visibility: visible; width: 1em; - height: 1em; left: -1em; top: 65px; cursor: pointer; - text-align: center; - vertical-align: middle; +} + +.page-header + .sub-page-header { + margin-top: -15px; } a:not([href]) { @@ -106,7 +129,8 @@ p { } .index-entry { - margin-left: 20px; + padding-bottom: 9px; + border-bottom: 1px solid #eee; } .doxtable th, @@ -169,28 +193,10 @@ dl.section.user dd { margin-left: 20px; } -span.octicon { - margin-right: 5px; +i.octicon { + margin-right: 10px; } .strike { text-decoration: line-through; } - -#footer { - height: 100px; - font-size: 0.9em; - text-align: center; - padding-top: 20px; - border-top: 1px solid #EEEEEE; -} - -.social-btns .social-btn { - display: inline-block; - margin: 0; -} - -.github-btn { - overflow: hidden; - border: 0px none; -} diff --git a/doc/footer.html b/doc/footer.html index 33b4d7c9..1c2776db 100644 --- a/doc/footer.html +++ b/doc/footer.html @@ -5,13 +5,9 @@
-
- - - - + diff --git a/doc/header.html b/doc/header.html index 3ad44c28..1ca9259c 100644 --- a/doc/header.html +++ b/doc/header.html @@ -15,6 +15,23 @@ + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - - + + - - - - - - - - - - - - diff --git a/doc/manual.md b/doc/manual.md index b1cbeb2d..aa299898 100644 --- a/doc/manual.md +++ b/doc/manual.md @@ -1,11 +1,11 @@ -# Documentation {#mainpage} +# Introduction {#mainpage} \tableofcontents Metal is a [portable](#portability) header-only [C++14] library designed to make [template metaprogramming][tmp] enjoyable. -To that end, it provides a powerful high-level [abstraction](#concepts) for -compile-time algorithms that mimic the [standard algorithms library][algorithm], +It provides a powerful high-level [abstraction](#concepts) for compile-time +algorithms that mimic the [standard algorithms library][algorithm], hence **Metal** - Metaprogramming Algorithms. Motivation {#motivation} @@ -22,7 +22,7 @@ Contrary to the C preprocessor, it has long been noticed that thus consolidating template metaprogramming as the standard idiom for compile time computations in C++. -In March of 2003 the [Boost Metaprogramming Library][Boost.MPL], +In March of 2003 the [Boost Metaprogramming Library (MPL)][Boost.MPL], by Aleksey Gurtovoy and David Abrahams, is officially shipped with Boost version 1.30.0. A masterpiece of template metaprogramming, @@ -91,7 +91,7 @@ Installing {#installing} -------------------------------------------------------------------------------- Metal may optionally be installed system-wide to ease integration with external -projects, but if you'd rather use Metal locally, you may skip to the +projects. If you'd rather use Metal locally, you may skip to the [next section](#using_metal). Make sure to have [CMake] v2.8.12 or newer installed on your system, then, @@ -113,8 +113,8 @@ include tree. If you chose to [install Metal system-wide](#installing), make sure the installation prefix is looked up by your compiler. -If you use [CMake] it should suffice to add the following to your project's -configuration. +In case you use [CMake] to automate building your projects, it should suffice to +add the following to the `CMakeLists.txt`. find_package(Metal REQUIRED) include_directories(${METAL_INCLUDE_DIRS}) @@ -152,24 +152,26 @@ The documentation will be generated into `doc/html/`. To browse the documentation offline, simply load `index.html` on any web browser that supports [JavaScript]. -Header Organization {#header_organization} +Project Organization {#project_organization} -------------------------------------------------------------------------------- -Each header in Metal is named after the construct it defines, -so for instance `distinct.hpp` defines `metal::distinct`, -while `enumerate.hpp` defines `metal::enumerate`. +Metal is designed to be fine grained and intuitive. Header files define a single +algorithm each, after which they are named, and are semantically organized +within directories that represent modules. For convenience, along each directory +one also finds a homonimous header file that includes everything therein, that +is, every header file pertaining to that module. The complete hierarchy of +modules and their header files is available on +[Metal's GitHub repository][Metal.headers]. -Headers are semantically organized within modules named after the various -[concepts](#concepts). Each module corresponds to a directory in the filesystem, -which may also contain sub-directories, that is, sub-modules. -For convenience, along each directory one finds a homonimous header file that -includes everything therein. The complete hierarchy of modules and headers is -available in the [Headers](files.html) tab. +Each module is named after a [concept](#concepts) and contains algorithms that +operate on models of that concept. The complete reference documentation for the +modules and their algorithms is available in section [Reference](modules.html). -\danger{ - Headers within `detail/` are undocumented and should be expected to +\warning{ + Header files within `detail/` are undocumented and should be expected to undergo breaking changes without prior notice. Directly depending on these - headers or on `namespace metal::detail` is strongly discouraged. + header files or, likewise, on any name that is defined within + `namespace metal::detail` is strongly discouraged. } Portability {#portability} @@ -223,6 +225,16 @@ if your favorite compiler is not included, please [let us know][Metal.issues]. might be due to a temporary network downtime. } +Benchmarks {#benchmarks} +================================================================================ + +To make sure Metal does not slow compilation times even when manipulating +hundreds or even thousands of types at a time, a comprehensive set of benchmarks +has been set up at [Metabench] to help keeping track of Metal's performance +against some of the most popular metaprogramming libraries available out there. +Benchmark results are updated nightly for various supported compilers and should +reflect the performance delivered by Metal at branch `master`. + Concepts {#concepts} ================================================================================ @@ -272,6 +284,7 @@ A [Number] is a compile-time representation of a numerical value. \snippet number.cpp num1 \snippet number.cpp num2 +\snippet number.cpp num3 ### Counterexamples @@ -420,24 +433,25 @@ about its arguments, which may very well be unknown at compile-time. So how can we convince the compiler that indices are always known at compile-time? We refactor the subscript operator to take an instance of -`metal::number`. +`metal::number` instead. \snippet literal.cpp augmented_tuple -Since `i` in this context is already a template argument, the compiler has no -reason to complain about passing it on as an argument to other template -instantiations. +Using template patern matching, we can extract the underlying value `i`, which +in this context is already a template argument and thus guaranteed to be known +at compile-time, so compilers have no reason to object to passing it on as +an argument to other template instantiations. \snippet literal.cpp teaser_3 That looks promising, but then again isn't `metal::number<1>{}` just as clunky as `std::get<1>()`? Yes. Absolutely. -That's where [literal operators][literal] come into play. +That's where [literal operators][literal] shine. \snippet literal.cpp teaser_4 -We're are getting there, but how is `_c` implemented again? +We're are getting there, but how is `_c` implemented? At a first glance it might be tempting to try something like this @@ -445,14 +459,14 @@ At a first glance it might be tempting to try something like this \snippet literal.cpp naive_2 } -but do not forget why we're here to begin with, recall we can't instantiate -a template using a non-constexpr variable as argument! +but do not forget why we're here to begin with, that is, recall we can't +instantiate a template using a non-constexpr variable as argument! At this point, a watchful reader might argue that in theory there is no real reason for this to be rejected, since the literal value must always be known at compile-time and that makes a lot of sense indeed, but unfortunately that's just not how it works. All is not lost however, because we can still parse raw -literals, that is, we are in for some fun! +literals, which means we are in for some fun! ### The Raw Literal Operator Template @@ -474,8 +488,8 @@ as well as digit separators We start by defining the literal operator `_c` as a function that forwards the raw literal characters as a [List] of [Numbers] to `parse_number` and returns a -default constructed object of whatever type aliases to. -In this case it is guaranteed to be a [Number]. +default constructed object of whatever type it aliases to, which in this case +is guaranteed to be a [Number]. \snippet literal.cpp _c @@ -561,7 +575,7 @@ specific purpose and construct a [Lambda] from it, much like we did for If *bind expressions* look scary to you, don't panic, we will cover [Expression] composition in detail in our [next practical example](#church_booleans). Here it suffices to know that *bind expressions* are themselves [Lambdas] and -that `metal::_1` and `metal::_2` are [Placeholders] that get substituted by the +that `metal::_1` and `metal::_2` are *placeholders* that get substituted by the first and second arguments with which the *bind expression* is invoked prior to the recursive evaluation of the [Expressions] that compose the *bind expression*. @@ -572,7 +586,7 @@ That's where `metal::apply` comes into play. \snippet literal.cpp sum -And there you go +And there we have it \snippet literal.cpp assemble_number @@ -611,8 +625,6 @@ TODO [Pairs]: #pair [Map]: #map [Maps]: #map -[Placeholder]: \ref placeholders -[Placeholders]: \ref placeholders [C++11]: http://en.wikipedia.org/wiki/C%2B%2B11 [C++14]: http://en.wikipedia.org/wiki/C%2B%2B14 @@ -645,8 +657,8 @@ TODO [Boost.MPL]: http://boost.org/doc/libs/1_60_0/libs/mpl/doc [Boost.Hana]: http://boostorg.github.io/hana -[meta]: http://github.com/ericniebler/meta -[turbo]: http://github.com/Manu343726/Turbo +[Meta]: http://github.com/ericniebler/meta +[Brigand]: http://github.com/edouarda/brigand [mpl.lite]: http://rrsd.com/blincubator.com/bi_suggestion/mpl-lite-or-mpl2/ @@ -660,3 +672,6 @@ TODO [Metal.issues]: http://github.com/brunocodutra/metal/issues [Metal.latest]: http://github.com/brunocodutra/metal/archive/master.zip +[Metal.headers]: http://github.com/brunocodutra/metal/tree/master/include + +[Metabench]: http://brunocodutra.github.io/metabench/ diff --git a/example/CMakeLists.txt b/example/CMakeLists.txt index 0bcc7dca..186b7b70 100644 --- a/example/CMakeLists.txt +++ b/example/CMakeLists.txt @@ -2,7 +2,8 @@ # Distributed under the Boost Software License, Version 1.0. # See accompanying file LICENSE.txt or copy at http://boost.org/LICENSE_1_0.txt +include_directories("${METAL_INCLUDE_DIR}") include_directories("${CMAKE_CURRENT_SOURCE_DIR}/include/") add_custom_target(examples) -metal_add_test_tree(examples "${CMAKE_CURRENT_SOURCE_DIR}/src/") +metal_build_test_tree(examples "${CMAKE_CURRENT_SOURCE_DIR}/src/") diff --git a/example/external/CMakeLists.txt b/example/external/CMakeLists.txt index 894b8fef..e1352d55 100644 --- a/example/external/CMakeLists.txt +++ b/example/external/CMakeLists.txt @@ -8,7 +8,10 @@ project(external CXX) set(FIND_PACKAGE_ARGS REQUIRED) if(METAL_VERSION) - set(FIND_PACKAGE_ARGS ${METAL_VERSION} EXACT ${FIND_PACKAGE_ARGS}) + if(METAL_VERSION_EXACT) + set(FIND_PACKAGE_ARGS EXACT ${FIND_PACKAGE_ARGS}) + endif() + set(FIND_PACKAGE_ARGS ${METAL_VERSION} ${FIND_PACKAGE_ARGS}) endif() find_package(Metal ${FIND_PACKAGE_ARGS}) diff --git a/example/src/literal.cpp b/example/src/literal.cpp index dfb5abdd..615dfc44 100644 --- a/example/src/literal.cpp +++ b/example/src/literal.cpp @@ -291,34 +291,34 @@ IS_SAME( ); ///[_c_ex3] -#if __cpp_constexpr >= 201304 -///[augmented_tuple] +#if defined(METAL_COMPAT_MODE) template struct AugmentedTuple : std::tuple { - using std::tuple::tuple; + template + constexpr AugmentedTuple(U&&... args) : + std::tuple(std::forward(args)...) + {} template - constexpr auto operator [](metal::number) - -> std::tuple_element_t>& { + constexpr auto operator [](metal::number) const + -> std::tuple_element_t> { return std::get(*this); } }; ///[augmented_tuple] #else +///[augmented_tuple] template struct AugmentedTuple : std::tuple { - template - constexpr AugmentedTuple(U&&... args) : - std::tuple(std::forward(args)...) - {} + using std::tuple::tuple; template - constexpr auto operator [](metal::number) const - -> std::tuple_element_t> { + constexpr auto operator [](metal::number) + -> std::tuple_element_t>& { return std::get(*this); } }; diff --git a/example/src/map.cpp b/example/src/map.cpp index aada3322..05d8dc8d 100644 --- a/example/src/map.cpp +++ b/example/src/map.cpp @@ -46,3 +46,34 @@ using not_a_map = metal::list< // not a list of pairs IS_SAME(metal::is_map, metal::false_); ) + +HIDE( +/// [keys] +using map = metal::map< + metal::pair>, + metal::pair>, + metal::pair> +>; + +IS_SAME(metal::keys, metal::list); +/// [keys] +) + +HIDE( +/// [values] +using map = metal::map< + metal::pair>, + metal::pair>, + metal::pair> +>; + +IS_SAME( + metal::values, + metal::list< + metal::number, + metal::number, + metal::number + > +); +/// [values] +) diff --git a/example/src/number.cpp b/example/src/number.cpp index 37e9a11a..e374e728 100644 --- a/example/src/number.cpp +++ b/example/src/number.cpp @@ -22,6 +22,14 @@ using num = metal::number<-1>; IS_SAME(metal::is_number, metal::true_); ) +HIDE( +/// [num3] +using num = metal::number<'a'>; +/// [num3] + +IS_SAME(metal::is_number, metal::true_); +) + HIDE( /// [not_a_num1] struct not_a_num : @@ -41,6 +49,22 @@ IS_SAME(metal::is_number, metal::false_); /// [is_number] ) +HIDE( +/// [numbers] +IS_SAME(metal::numbers<>, metal::list<>); + +IS_SAME( + metal::numbers<'a', 'b'>, + metal::list, metal::number<'b'>> +); + +IS_SAME( + metal::numbers<-7, 5, 1>, + metal::list, metal::number<5>, metal::number<1>> +); +/// [numbers] +) + HIDE( /// [if_] IS_SAME(metal::if_, int*, void>, void); @@ -76,21 +100,22 @@ IS_SAME(metal::not_, metal::false_); HIDE( /// [and_] -using num = metal::and_, metal::number<0>, metal::number<5>>; - -IS_SAME(num, metal::false_); +IS_SAME(metal::and_<>, metal::true_); +IS_SAME(metal::and_>, metal::false_); +IS_SAME(metal::and_>, metal::true_); +IS_SAME(metal::and_, metal::number<0>>, metal::false_); /// [and_] ) HIDE( /// [or_] -using num = metal::or_, metal::number<0>, metal::number<5>>; - -IS_SAME(num, metal::true_); +IS_SAME(metal::or_<>, metal::false_); +IS_SAME(metal::or_>, metal::false_); +IS_SAME(metal::or_>, metal::true_); +IS_SAME(metal::or_, metal::number<0>>, metal::true_); /// [or_] ) - HIDE( /// [inc] IS_SAME(metal::inc>, metal::number<-9>); @@ -114,31 +139,31 @@ IS_SAME(metal::neg>, metal::number<0>); HIDE( /// [add] -using num = metal::add, metal::number<5>, metal::number<1>>; +using num = metal::add, metal::number<5>, metal::number<3>>; -IS_SAME(num, metal::number<-1>); +IS_SAME(num, metal::number<-9>); /// [add] ) HIDE( /// [sub] -using num = metal::sub, metal::number<5>, metal::number<1>>; +using num = metal::sub, metal::number<5>, metal::number<3>>; -IS_SAME(num, metal::number<-13>); +IS_SAME(num, metal::number<-25>); /// [sub] ) HIDE( /// [mul] -using num = metal::mul, metal::number<5>, metal::number<1>>; +using num = metal::mul, metal::number<5>, metal::number<3>>; -IS_SAME(num, metal::number<-35>); +IS_SAME(num, metal::number<-255>); /// [mul] ) HIDE( /// [div] -using num = metal::div, metal::number<5>, metal::number<1>>; +using num = metal::div, metal::number<5>, metal::number<3>>; IS_SAME(num, metal::number<-1>); IS_SAME( @@ -150,9 +175,9 @@ IS_SAME( HIDE( /// [mod] -using num = metal::mod, metal::number<5>, metal::number<1>>; +using num = metal::mod, metal::number<5>, metal::number<3>>; -IS_SAME(num, metal::number<0>); +IS_SAME(num, metal::number<-2>); IS_SAME( metal::is_invocable, num, metal::number<0>>, metal::false_ @@ -162,9 +187,9 @@ IS_SAME( HIDE( /// [pow] -using num = metal::pow, metal::number<5>, metal::number<1>>; +using num = metal::pow, metal::number<5>, metal::number<3>>; -IS_SAME(num, metal::number<-16807>); +IS_SAME(num, metal::number<-2862423051509815793>); IS_SAME( metal::is_invocable, metal::number<0>, num>, metal::false_ @@ -174,7 +199,7 @@ IS_SAME( HIDE( /// [max] -using num = metal::max, metal::number<5>, metal::number<1>>; +using num = metal::max, metal::number<5>, metal::number<3>>; IS_SAME(num, metal::number<5>); /// [max] @@ -182,9 +207,9 @@ IS_SAME(num, metal::number<5>); HIDE( /// [min] -using num = metal::min, metal::number<5>, metal::number<1>>; +using num = metal::min, metal::number<5>, metal::number<3>>; -IS_SAME(num, metal::number<-7>); +IS_SAME(num, metal::number<-17>); /// [min] ) diff --git a/example/src/value.cpp b/example/src/value.cpp index cc015569..51b40f06 100644 --- a/example/src/value.cpp +++ b/example/src/value.cpp @@ -55,3 +55,60 @@ struct not_a_val }; /// [not_a_val3] ) + +HIDE( +/// [value] +using num = metal::number<42>; +IS_SAME(metal::is_number>, metal::false_); +IS_SAME(metal::value::type, num); + +using lbd = metal::lambda; +IS_SAME(metal::is_lambda>, metal::false_); +IS_SAME(metal::value::type, lbd); + +using list = metal::list<>; +IS_SAME(metal::is_list>, metal::false_); +IS_SAME(metal::value::type, list); +/// [value] +) + +HIDE( +/// [is_value] +template +struct has_type_impl : + metal::false_ +{}; + +template +struct has_type_impl> : + metal::true_ +{}; + +template +using has_type = typename has_type_impl::type; + + +IS_SAME(has_type>, metal::true_); +IS_SAME(has_type>, metal::false_); +/// [is_value] +) + +HIDE( +/// [same] +IS_SAME(metal::same<>, metal::true_); +IS_SAME(metal::same, metal::true_); +IS_SAME(metal::same, metal::true_); +IS_SAME(metal::same, metal::false_); +IS_SAME(metal::same, metal::false_); +/// [same] +) + +HIDE( +/// [distinct] +IS_SAME(metal::distinct<>, metal::true_); +IS_SAME(metal::distinct, metal::true_); +IS_SAME(metal::distinct, metal::false_); +IS_SAME(metal::distinct, metal::false_); +IS_SAME(metal::distinct, metal::true_); +/// [distinct] +) diff --git a/include/metal.hpp b/include/metal.hpp index 682a7f85..9604c595 100644 --- a/include/metal.hpp +++ b/include/metal.hpp @@ -5,6 +5,7 @@ #ifndef METAL_HPP #define METAL_HPP +#include #include #include #include diff --git a/include/metal/config.hpp b/include/metal/config.hpp new file mode 100644 index 00000000..45ccd0db --- /dev/null +++ b/include/metal/config.hpp @@ -0,0 +1,14 @@ +// Copyright Bruno Dutra 2015-2016 +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE.txt or copy at http://boost.org/LICENSE_1_0.txt + +#ifndef METAL_CONFIG_HPP +#define METAL_CONFIG_HPP + +#include +#include + +/// \defgroup config Config +/// \ingroup metal + +#endif diff --git a/include/metal/config/config.hpp b/include/metal/config/config.hpp new file mode 100644 index 00000000..1b83aa0c --- /dev/null +++ b/include/metal/config/config.hpp @@ -0,0 +1,39 @@ +// Copyright Bruno Dutra 2015-2016 +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE.txt or copy at http://boost.org/LICENSE_1_0.txt + +#ifndef METAL_CONFIG_CONFIG_HPP +#define METAL_CONFIG_CONFIG_HPP + +/// \ingroup config +/// +/// ### Description +/// When this preprocessor switch is defined, certain language features that +/// are known to cause problems to some compilers are avoided. +/// +/// \warning{ +/// Defining this preprocessor switch may lead to longer compilation times. +/// } +/// +/// \note{ +/// This preprocessor switch is currently defined by default for all +/// versions of Microsoft Visual Studio. +/// } +#if defined(METAL_DOXYGENATING) || \ + (!defined(METAL_COMPAT_MODE) && defined(_MSC_VER) && !defined(__clang__)) +# define METAL_COMPAT_MODE +#endif + +#if defined(_MSC_VER) && !defined(__clang__) +# define METAL_WARNING(MSG) __pragma(message("warning: "MSG)) +#else +# define METAL_WARNING_IMPL(MSG) _Pragma(#MSG) +# define METAL_WARNING(MSG) METAL_WARNING_IMPL(GCC warning MSG) +#endif + +#if (defined(_MSC_VER) && (_MSC_VER < 1900) && !defined(__clang__)) || \ + (!defined(_MSC_VER) && (__cplusplus < 201402L)) + METAL_WARNING("your compiler does not appear to support C++14 properly") +#endif + +#endif diff --git a/include/metal/config/version.hpp b/include/metal/config/version.hpp new file mode 100644 index 00000000..321871b8 --- /dev/null +++ b/include/metal/config/version.hpp @@ -0,0 +1,55 @@ +// Copyright Bruno Dutra 2015-2016 +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE.txt or copy at http://boost.org/LICENSE_1_0.txt + +#ifndef METAL_CONFIG_VERSION_HPP +#define METAL_CONFIG_VERSION_HPP + +/// \ingroup config +/// +/// ### Description +/// Expands to the major version of Metal. +/// +/// ### See Also +/// \see [Semantic Versioning](http://semver.org/) +#define METAL_MAJOR 0 + +/// \ingroup config +/// +/// ### Description +/// Expands to the minor version of Metal. +/// +/// ### See Also +/// \see [Semantic Versioning](http://semver.org/) +#define METAL_MINOR 3 + +/// \ingroup config +/// +/// ### Description +/// Expands to the patch version of Metal. +/// +/// ### See Also +/// \see [Semantic Versioning](http://semver.org/) +#define METAL_PATCH 0 + +/// \ingroup config +/// \hideinitializer +/// +/// ### Description +/// Given a `{major, minor, patch}` triple, expands to an implementation defined +/// integral constant that is guaranteed to be comparable according to +/// [Semantic Versioning](http://semver.org/) rules. +/// +/// ### See Also +/// \see [Semantic Versioning](http://semver.org/) +#define METAL_SEMVER(MAJOR, MINOR, PATCH) \ + (((MAJOR) * 1000000) + ((MINOR) * 10000) + (PATCH)) + +/// \ingroup config +/// Expands to the full version of Metal. +/// +/// ### See Also +/// \see [Semantic Versioning](http://semver.org/) +#define METAL_VERSION METAL_SEMVER(METAL_MAJOR, METAL_MINOR, METAL_PATCH) + +#endif diff --git a/include/metal/detail/fold_cons.hpp b/include/metal/detail/fold_cons.hpp new file mode 100644 index 00000000..9b33b0de --- /dev/null +++ b/include/metal/detail/fold_cons.hpp @@ -0,0 +1,70 @@ +// Copyright Bruno Dutra 2015-2016 +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE.txt or copy at http://boost.org/LICENSE_1_0.txt + +#ifndef METAL_DETAIL_FOLD_CONS_HPP +#define METAL_DETAIL_FOLD_CONS_HPP + +#include +#include +#include +#include + +namespace metal +{ + namespace detail + { + template + struct _fold_cons + {}; + + template< + typename a, typename b, typename c, typename d, + typename e, typename f, typename g, typename h, + typename i, typename j, typename k, typename l, + typename m, typename n, typename o, typename p, typename tail, + typename state, template class expr + > + struct _fold_cons< + list, + state, + lambda, + is_value< + expr, b>, c>, d>, e>, f>, g>, h>, + i>, j>, k>, l>, m>, n>, o>, p> + > + > : + _fold_cons< + tail, + expr, b>, c>, d>, e>, f>, g>, h>, + i>, j>, k>, l>, m>, n>, o>, p>, + lambda + > + {}; + + template< + typename head, typename tail, + typename state, template class expr + > + struct _fold_cons, state, lambda, + is_value> + > : + _fold_cons, lambda> + {}; + + template class expr> + struct _fold_cons, state, lambda> + { + using type = state; + }; + } +} + +#endif + diff --git a/include/metal/detail/pick.hpp b/include/metal/detail/pick.hpp new file mode 100644 index 00000000..b6f3135e --- /dev/null +++ b/include/metal/detail/pick.hpp @@ -0,0 +1,38 @@ +// Copyright Bruno Dutra 2015-2016 +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE.txt or copy at http://boost.org/LICENSE_1_0.txt + +#ifndef METAL_DETAIL_PICK_HPP +#define METAL_DETAIL_PICK_HPP + +#include +#include +#include +#include + +namespace metal +{ + namespace detail + { + template + struct _pick + {}; + + template<> + struct _pick, list<>> + { + using type = list<>; + }; + + template + struct _pick, list...>> : + _join, list, list<>>...> + {}; + + template + using pick = typename _pick::type; + } +} + +#endif + diff --git a/include/metal/lambda.hpp b/include/metal/lambda.hpp index d8cde675..c5d244d3 100644 --- a/include/metal/lambda.hpp +++ b/include/metal/lambda.hpp @@ -5,6 +5,8 @@ #ifndef METAL_LAMBDA_HPP #define METAL_LAMBDA_HPP +#include + #include #include #include diff --git a/include/metal/lambda/apply.hpp b/include/metal/lambda/apply.hpp index 0480d2c7..1073f4f1 100644 --- a/include/metal/lambda/apply.hpp +++ b/include/metal/lambda/apply.hpp @@ -5,11 +5,15 @@ #ifndef METAL_LAMBDA_APPLY_HPP #define METAL_LAMBDA_APPLY_HPP +#include + #include namespace metal { /// \ingroup lambda + /// + /// ### Description /// ... template using apply = typename detail::_invoke_impl::type; diff --git a/include/metal/lambda/arg.hpp b/include/metal/lambda/arg.hpp index 7f1baded..1c7c2b19 100644 --- a/include/metal/lambda/arg.hpp +++ b/include/metal/lambda/arg.hpp @@ -5,8 +5,10 @@ #ifndef METAL_LAMBDA_ARG_HPP #define METAL_LAMBDA_ARG_HPP -#include +#include + #include +#include #include #include @@ -31,11 +33,15 @@ namespace metal } /// \ingroup lambda + /// + /// ### Description /// ... template using arg = typename detail::arg_impl::type; /// \ingroup lambda + /// + /// ### Description /// Default placeholder. /// \{ using _1 = metal::arg<1U>; diff --git a/include/metal/lambda/bind.hpp b/include/metal/lambda/bind.hpp index 6280dd6b..763cf163 100644 --- a/include/metal/lambda/bind.hpp +++ b/include/metal/lambda/bind.hpp @@ -5,6 +5,8 @@ #ifndef METAL_LAMBDA_BIND_HPP #define METAL_LAMBDA_BIND_HPP +#include + namespace metal { namespace detail @@ -14,6 +16,8 @@ namespace metal } /// \ingroup lambda + /// + /// ### Description /// ... template using bind = typename detail::_bind::type; diff --git a/include/metal/lambda/invoke.hpp b/include/metal/lambda/invoke.hpp index bc199112..fa05a8e1 100644 --- a/include/metal/lambda/invoke.hpp +++ b/include/metal/lambda/invoke.hpp @@ -5,6 +5,8 @@ #ifndef METAL_LAMBDA_INVOKE_HPP #define METAL_LAMBDA_INVOKE_HPP +#include + #include #include #include @@ -24,11 +26,15 @@ namespace metal } /// \ingroup lambda + /// + /// ### Description /// ... template using invoke = typename detail::_invoke::type; /// \ingroup lambda + /// + /// ### Description /// ... template using is_invocable = same< diff --git a/include/metal/lambda/lambda.hpp b/include/metal/lambda/lambda.hpp index 792fd6e6..ca82a32a 100644 --- a/include/metal/lambda/lambda.hpp +++ b/include/metal/lambda/lambda.hpp @@ -5,6 +5,8 @@ #ifndef METAL_LAMBDA_LAMBDA_HPP #define METAL_LAMBDA_LAMBDA_HPP +#include + namespace metal { namespace detail @@ -17,11 +19,15 @@ namespace metal } /// \ingroup lambda + /// + /// ### Description /// ... template using is_lambda = typename detail::_is_lambda::type; /// \ingroup lambda + /// + /// ### Description /// ... template class expr> using lambda = detail::lambda; diff --git a/include/metal/lambda/partial.hpp b/include/metal/lambda/partial.hpp index bc5afd7f..1f0ecc77 100644 --- a/include/metal/lambda/partial.hpp +++ b/include/metal/lambda/partial.hpp @@ -5,6 +5,8 @@ #ifndef METAL_LAMBDA_PARTIAL_HPP #define METAL_LAMBDA_PARTIAL_HPP +#include + namespace metal { namespace detail @@ -14,6 +16,8 @@ namespace metal } /// \ingroup lambda + /// + /// ### Description /// ... template using partial = typename detail::_partial::type; diff --git a/include/metal/lambda/quote.hpp b/include/metal/lambda/quote.hpp index de42011a..1fccdc8e 100644 --- a/include/metal/lambda/quote.hpp +++ b/include/metal/lambda/quote.hpp @@ -5,6 +5,8 @@ #ifndef METAL_LAMBDA_QUOTE_HPP #define METAL_LAMBDA_QUOTE_HPP +#include + namespace metal { namespace detail @@ -14,6 +16,8 @@ namespace metal } /// \ingroup lambda + /// + /// ### Description /// ... template using quote = typename detail::_quote::type; diff --git a/include/metal/list.hpp b/include/metal/list.hpp index 450ee752..67e5cde0 100644 --- a/include/metal/list.hpp +++ b/include/metal/list.hpp @@ -5,8 +5,11 @@ #ifndef METAL_LIST_HPP #define METAL_LIST_HPP +#include + #include #include +#include #include #include #include @@ -14,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -28,10 +32,7 @@ #include #include #include -#include -#include -#include -#include +#include #include #include #include @@ -42,6 +43,7 @@ #include #include #include +#include #include #include diff --git a/include/metal/list/all.hpp b/include/metal/list/all.hpp index 972f54f1..7744bff6 100644 --- a/include/metal/list/all.hpp +++ b/include/metal/list/all.hpp @@ -5,6 +5,8 @@ #ifndef METAL_LIST_ALL_HPP #define METAL_LIST_ALL_HPP +#include + #include #include #include @@ -13,6 +15,8 @@ namespace metal { /// \ingroup list + /// + /// ### Description /// ... template using all = diff --git a/include/metal/list/any.hpp b/include/metal/list/any.hpp index 08507e79..5ebc63e4 100644 --- a/include/metal/list/any.hpp +++ b/include/metal/list/any.hpp @@ -5,6 +5,8 @@ #ifndef METAL_LIST_ANY_HPP #define METAL_LIST_ANY_HPP +#include + #include #include #include @@ -13,6 +15,8 @@ namespace metal { /// \ingroup list + /// + /// ### Description /// ... template using any = diff --git a/include/metal/list/push_back.hpp b/include/metal/list/append.hpp similarity index 55% rename from include/metal/list/push_back.hpp rename to include/metal/list/append.hpp index cee5b670..eb60b360 100644 --- a/include/metal/list/push_back.hpp +++ b/include/metal/list/append.hpp @@ -2,8 +2,10 @@ // Distributed under the Boost Software License, Version 1.0. // See accompanying file LICENSE.txt or copy at http://boost.org/LICENSE_1_0.txt -#ifndef METAL_LIST_PUSH_BACK_HPP -#define METAL_LIST_PUSH_BACK_HPP +#ifndef METAL_LIST_APPEND_HPP +#define METAL_LIST_APPEND_HPP + +#include #include #include @@ -11,9 +13,11 @@ namespace metal { /// \ingroup list + /// + /// ### Description /// ... - template - using push_back = metal::join>; + template + using append = metal::join>; } #endif diff --git a/include/metal/list/at.hpp b/include/metal/list/at.hpp index 97f4f8e6..68ccfaf7 100644 --- a/include/metal/list/at.hpp +++ b/include/metal/list/at.hpp @@ -5,6 +5,8 @@ #ifndef METAL_LIST_AT_HPP #define METAL_LIST_AT_HPP +#include + #include #include @@ -12,6 +14,8 @@ namespace metal { /// \ingroup list + /// + /// ### Description /// ... template using at = detail::lookup, num>; diff --git a/include/metal/list/back.hpp b/include/metal/list/back.hpp index 6cf2b17b..68b08e6f 100644 --- a/include/metal/list/back.hpp +++ b/include/metal/list/back.hpp @@ -5,6 +5,8 @@ #ifndef METAL_LIST_BACK_HPP #define METAL_LIST_BACK_HPP +#include + #include #include #include @@ -12,6 +14,8 @@ namespace metal { /// \ingroup list + /// + /// ### Description /// ... template using back = metal::at>>; diff --git a/include/metal/list/contains.hpp b/include/metal/list/contains.hpp index a35655ee..c6c84cf7 100644 --- a/include/metal/list/contains.hpp +++ b/include/metal/list/contains.hpp @@ -5,6 +5,8 @@ #ifndef METAL_LIST_CONTAINS_HPP #define METAL_LIST_CONTAINS_HPP +#include + #include #include #include @@ -14,6 +16,8 @@ namespace metal { /// \ingroup list + /// + /// ### Description /// ... template using contains = diff --git a/include/metal/list/copy.hpp b/include/metal/list/copy.hpp index da51417d..88e73675 100644 --- a/include/metal/list/copy.hpp +++ b/include/metal/list/copy.hpp @@ -5,6 +5,8 @@ #ifndef METAL_LIST_COPY_HPP #define METAL_LIST_COPY_HPP +#include + #include #include #include @@ -13,6 +15,8 @@ namespace metal { /// \ingroup list + /// + /// ### Description /// ... template using copy = diff --git a/include/metal/list/copy_if.hpp b/include/metal/list/copy_if.hpp index 66154245..b2f19d62 100644 --- a/include/metal/list/copy_if.hpp +++ b/include/metal/list/copy_if.hpp @@ -5,47 +5,20 @@ #ifndef METAL_LIST_COPY_IF_HPP #define METAL_LIST_COPY_IF_HPP +#include + #include +#include + namespace metal { - namespace detail - { - template - struct _copy_if_impl; - } - /// \ingroup list + /// + /// ### Description /// ... template - using copy_if = - typename detail::_copy_if_impl>::type; -} - -#include -#include -#include -#include - -namespace metal -{ - namespace detail - { - template - struct _copy_if_impl - {}; - - template<> - struct _copy_if_impl, list<>> - { - using type = list<>; - }; - - template - struct _copy_if_impl, list...>> : - _join, list, list<>>...> - {}; - } + using copy_if = detail::pick>; } #endif diff --git a/include/metal/list/count.hpp b/include/metal/list/count.hpp index f7ca9138..6eef5db1 100644 --- a/include/metal/list/count.hpp +++ b/include/metal/list/count.hpp @@ -5,6 +5,8 @@ #ifndef METAL_LIST_COUNT_HPP #define METAL_LIST_COUNT_HPP +#include + #include #include #include @@ -13,6 +15,8 @@ namespace metal { /// \ingroup list + /// + /// ### Description /// ... template using count = diff --git a/include/metal/list/count_if.hpp b/include/metal/list/count_if.hpp index ec107de1..933201de 100644 --- a/include/metal/list/count_if.hpp +++ b/include/metal/list/count_if.hpp @@ -5,6 +5,8 @@ #ifndef METAL_LIST_COUNT_IF_HPP #define METAL_LIST_COUNT_IF_HPP +#include + #include #include #include @@ -15,6 +17,8 @@ namespace metal { /// \ingroup list + /// + /// ### Description /// ... template using count_if = metal::apply< diff --git a/include/metal/list/pop_back.hpp b/include/metal/list/drop.hpp similarity index 50% rename from include/metal/list/pop_back.hpp rename to include/metal/list/drop.hpp index 9642b866..fdbe111c 100644 --- a/include/metal/list/pop_back.hpp +++ b/include/metal/list/drop.hpp @@ -2,24 +2,22 @@ // Distributed under the Boost Software License, Version 1.0. // See accompanying file LICENSE.txt or copy at http://boost.org/LICENSE_1_0.txt -#ifndef METAL_LIST_POP_BACK_HPP -#define METAL_LIST_POP_BACK_HPP +#ifndef METAL_LIST_DROP_HPP +#define METAL_LIST_DROP_HPP + +#include -#include #include -#include -#include +#include namespace metal { /// \ingroup list + /// + /// ### Description /// ... - template> - using pop_back = metal::range< - seq, - metal::number<0>, - metal::sub, n> - >; + template + using drop = metal::range>; } #endif diff --git a/include/metal/list/empty.hpp b/include/metal/list/empty.hpp index e8d0758b..b1257545 100644 --- a/include/metal/list/empty.hpp +++ b/include/metal/list/empty.hpp @@ -5,12 +5,16 @@ #ifndef METAL_LIST_EMPTY_HPP #define METAL_LIST_EMPTY_HPP +#include + #include #include namespace metal { /// \ingroup list + /// + /// ### Description /// ... template using empty = metal::not_>; diff --git a/include/metal/list/erase.hpp b/include/metal/list/erase.hpp index c486cd62..5d3495d9 100644 --- a/include/metal/list/erase.hpp +++ b/include/metal/list/erase.hpp @@ -5,10 +5,11 @@ #ifndef METAL_LIST_ERASE_HPP #define METAL_LIST_ERASE_HPP +#include + #include -#include -#include -#include +#include +#include #include #include #include @@ -16,11 +17,13 @@ namespace metal { /// \ingroup list + /// + /// ### Description /// ... template> using erase = metal::join< - metal::range, metal::min>, - metal::range, metal::size> + metal::take>, + metal::drop> >; } diff --git a/include/metal/list/find.hpp b/include/metal/list/find.hpp index 24158796..5308046e 100644 --- a/include/metal/list/find.hpp +++ b/include/metal/list/find.hpp @@ -5,6 +5,8 @@ #ifndef METAL_LIST_FIND_HPP #define METAL_LIST_FIND_HPP +#include + #include #include #include @@ -13,6 +15,8 @@ namespace metal { /// \ingroup list + /// + /// ### Description /// ... template using find = diff --git a/include/metal/list/find_if.hpp b/include/metal/list/find_if.hpp index e1a44cfa..585b2a90 100644 --- a/include/metal/list/find_if.hpp +++ b/include/metal/list/find_if.hpp @@ -5,6 +5,8 @@ #ifndef METAL_LIST_FIND_IF_HPP #define METAL_LIST_FIND_IF_HPP +#include + #include namespace metal @@ -16,6 +18,8 @@ namespace metal } /// \ingroup list + /// + /// ### Description /// ... template using find_if = typename detail::_find_if_impl>::type; @@ -44,22 +48,7 @@ namespace metal number<0> {}; -#if __cpp_constexpr >= 201304 - template - constexpr int_ ifind(_... vs) { - int_ ret = 0; - for(int_ x : std::initializer_list{vs...}) - if(x) break; - else ++ret; - - return ret; - } - - template - struct _find_if_impl...>> : - number - {}; -#else +#if defined(METAL_COMPAT_MODE) template> struct _find_index {}; @@ -76,6 +65,21 @@ namespace metal struct _find_if_impl...>> : _find_index...>> {}; +#else + template + constexpr int_ find_index(_... vs) { + int_ ret = 0; + for(int_ x : std::initializer_list{vs...}) + if(x) break; + else ++ret; + + return ret; + } + + template + struct _find_if_impl...>> : + number + {}; #endif } } diff --git a/include/metal/list/flatten.hpp b/include/metal/list/flatten.hpp index 13ddcdc9..e751f64d 100644 --- a/include/metal/list/flatten.hpp +++ b/include/metal/list/flatten.hpp @@ -5,6 +5,8 @@ #ifndef METAL_LIST_FLATTEN_HPP #define METAL_LIST_FLATTEN_HPP +#include + namespace metal { namespace detail @@ -14,6 +16,8 @@ namespace metal } /// \ingroup list + /// + /// ### Description /// ... template using flatten = typename detail::_flatten::type; diff --git a/include/metal/list/fold_left.hpp b/include/metal/list/fold_left.hpp index c20ee944..8d4fa71e 100644 --- a/include/metal/list/fold_left.hpp +++ b/include/metal/list/fold_left.hpp @@ -5,106 +5,32 @@ #ifndef METAL_LIST_FOLD_LEFT_HPP #define METAL_LIST_FOLD_LEFT_HPP +#include + namespace metal { namespace detail { - template - struct _fold_cons; - template struct _fold_left; } /// \ingroup list + /// + /// ### Description /// ... template using fold_left = typename detail::_fold_left::type; } #include -#include -#include + +#include namespace metal { namespace detail { - template - struct _fold_cons_impl - {}; - - template< - typename a, typename b, typename c, typename d, - typename e, typename f, typename g, typename h, - typename i, typename j, typename k, typename l, - typename m, typename n, typename o, typename p, typename t, - typename state, template class expr - > - struct _fold_cons_impl< - list, - state, - lambda, - is_value< - expr, b>, c>, d>, e>, f>, g>, h>, - i>, j>, k>, l>, m>, n>, o>, p> - > - > : - _fold_cons_impl< - t, - expr, b>, c>, d>, e>, f>, g>, h>, - i>, j>, k>, l>, m>, n>, o>, p>, - lambda - > - {}; - - template< - typename a, typename b, typename c, typename t, - typename state, template class expr - > - struct _fold_cons_impl, state, lambda, - is_value, b>, c>> - > : - _fold_cons_impl, b>, c>, lambda> - {}; - - template< - typename a, typename b, typename t, - typename state, template class expr - > - struct _fold_cons_impl, state, lambda, - is_value, b>> - > : - _fold_cons_impl, b>, lambda> - {}; - - template< - typename a, typename t, - typename state, template class expr - > - struct _fold_cons_impl, state, lambda, - is_value> - > : - _fold_cons_impl, lambda> - {}; - - template class expr> - struct _fold_cons_impl, state, lambda> - { - using type = state; - }; - - template - struct _fold_cons : - _fold_cons_impl - {}; - template struct _cons_left {}; @@ -116,31 +42,22 @@ namespace metal typename a, typename b, typename c, typename d, typename e, typename f, typename g, typename h, typename i, typename j, typename k, typename l, - typename m, typename n, typename o, typename p, typename... t + typename m, typename n, typename o, typename p, typename... tail + > + struct _cons_left< + a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, tail... > - struct _cons_left { using type = list< - a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, cons_left + a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, + cons_left >; }; - template - struct _cons_left - { - using type = list>; - }; - - template - struct _cons_left - { - using type = list>; - }; - - template - struct _cons_left + template + struct _cons_left { - using type = list>; + using type = list>; }; template<> @@ -155,7 +72,7 @@ namespace metal template struct _fold_left, state, lbd> : - _fold_cons_impl, state, lbd> + _fold_cons, state, lbd> {}; } } diff --git a/include/metal/list/fold_right.hpp b/include/metal/list/fold_right.hpp index 21b1e526..751424ec 100644 --- a/include/metal/list/fold_right.hpp +++ b/include/metal/list/fold_right.hpp @@ -5,6 +5,8 @@ #ifndef METAL_LIST_FOLD_RIGHT_HPP #define METAL_LIST_FOLD_RIGHT_HPP +#include + namespace metal { namespace detail @@ -14,14 +16,16 @@ namespace metal } /// \ingroup list + /// + /// ### Description /// ... template using fold_right = typename detail::_fold_right::type; } #include -#include -#include + +#include namespace metal { @@ -39,33 +43,22 @@ namespace metal typename a, typename b, typename c, typename d, typename e, typename f, typename g, typename h, typename i, typename j, typename k, typename l, - typename m, typename n, typename o, typename p, typename... t + typename m, typename n, typename o, typename p, typename... tail > struct _cons_right< - _, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, t... + _, a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, tail... > { using type = cons_right< - list, t... + list, + tail... >; }; - template - struct _cons_right<_, a, b, c, t...> - { - using type = cons_right, t...>; - }; - - template - struct _cons_right<_, a, b> - { - using type = list; - }; - - template - struct _cons_right<_, a> + template + struct _cons_right<_, head, tail...> { - using type = list; + using type = cons_right, tail...>; }; template diff --git a/include/metal/list/front.hpp b/include/metal/list/front.hpp index 291912ce..4b6d91b7 100644 --- a/include/metal/list/front.hpp +++ b/include/metal/list/front.hpp @@ -5,12 +5,16 @@ #ifndef METAL_LIST_FRONT_HPP #define METAL_LIST_FRONT_HPP +#include + #include #include namespace metal { /// \ingroup list + /// + /// ### Description /// ... template using front = metal::at>; diff --git a/include/metal/list/indices.hpp b/include/metal/list/indices.hpp index cbce3dc6..a95bdaa2 100644 --- a/include/metal/list/indices.hpp +++ b/include/metal/list/indices.hpp @@ -5,6 +5,8 @@ #ifndef METAL_LIST_INDICES_HPP #define METAL_LIST_INDICES_HPP +#include + #include #include #include @@ -12,6 +14,8 @@ namespace metal { /// \ingroup list + /// + /// ### Description /// ... template using indices = metal::enumerate, metal::size>; diff --git a/include/metal/list/insert.hpp b/include/metal/list/insert.hpp index d26c3c6b..957f3542 100644 --- a/include/metal/list/insert.hpp +++ b/include/metal/list/insert.hpp @@ -5,12 +5,16 @@ #ifndef METAL_LIST_INSERT_HPP #define METAL_LIST_INSERT_HPP +#include + #include #include namespace metal { /// \ingroup list + /// + /// ### Description /// ... template using insert = metal::splice>; diff --git a/include/metal/list/join.hpp b/include/metal/list/join.hpp index 8dd94aec..5335dc16 100644 --- a/include/metal/list/join.hpp +++ b/include/metal/list/join.hpp @@ -5,32 +5,42 @@ #ifndef METAL_LIST_JOIN_HPP #define METAL_LIST_JOIN_HPP +#include + +#include +#include +#include + namespace metal { namespace detail { template struct _join; + + template + using join = typename _join::type; } /// \ingroup list + /// + /// ### Description /// ... template - using join = typename detail::_join::type; -} - -#include -#include -#include + using join = typename if_< + and_, is_list...>, + detail::_join + >::type; -namespace metal -{ namespace detail { template struct _join_impl {}; + template + using join_impl = typename _join_impl::type; + template< typename... a, typename... b, typename... c, typename... d, typename... e, typename... f, typename... g, typename... h, @@ -54,46 +64,77 @@ namespace metal > {}; - template - struct _join_impl, list, list, tail...> : - _join, tail...> - {}; - - template - struct _join_impl, list, list> - { - using type = list; - }; - template struct _join_impl, list> { using type = list; }; - template - struct _join> - { - using type = list; - }; - template - struct _join : - _join_impl + struct _join {}; -#if !defined(_MSC_VER) - template - struct _join, list, list...> - { - using type = list; - }; +#if !defined(METAL_COMPAT_MODE) + template< + typename a, typename b, typename c, typename d, + typename e, typename f, typename g, typename h, + typename i, typename j, typename k, typename l, + typename m, typename n, typename o, typename p, + typename head, typename... tail + > + struct _join< + a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, + list, list... + > : + _join_impl< + join_impl, + list + > + {}; #endif - template class... seq> - struct _join, list<>, seq<>...> : - _if_, seq<>...>, list> + template< + typename a, typename b, typename c, typename d, + typename e, typename f, typename g, typename h, + typename i, typename j, typename k, typename l, + typename m, typename n, typename o, typename p, + template class... _ + > + struct _join< + a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, + list<>, _<>... + > : + _join_impl {}; + + template< + typename a, typename b, typename c, typename d, + typename e, typename f, typename g, typename h, + typename i, typename j, typename k, typename l, + typename m, typename n, typename o, typename p, typename... tail + > + struct _join : + _join< + join_impl, + tail... + > + {}; + + template + struct _join : + _join, tail...> + {}; + + template + struct _join : + _join_impl + {}; + + template + struct _join + { + using type = a; + }; } } diff --git a/include/metal/list/list.hpp b/include/metal/list/list.hpp index 5888348b..a24bdbad 100644 --- a/include/metal/list/list.hpp +++ b/include/metal/list/list.hpp @@ -5,6 +5,8 @@ #ifndef METAL_LIST_LIST_HPP #define METAL_LIST_LIST_HPP +#include + namespace metal { namespace detail @@ -17,11 +19,15 @@ namespace metal } /// \ingroup list + /// + /// ### Description /// ... template using is_list = typename detail::_is_list::type; /// \ingroup list + /// + /// ### Description /// ... template using list = detail::list; diff --git a/include/metal/list/none.hpp b/include/metal/list/none.hpp index 64a804c6..6572d94e 100644 --- a/include/metal/list/none.hpp +++ b/include/metal/list/none.hpp @@ -5,12 +5,16 @@ #ifndef METAL_LIST_NONE_HPP #define METAL_LIST_NONE_HPP +#include + #include #include namespace metal { /// \ingroup list + /// + /// ### Description /// ... template using none = metal::not_>; diff --git a/include/metal/list/partition.hpp b/include/metal/list/partition.hpp index 976b380b..59a47edf 100644 --- a/include/metal/list/partition.hpp +++ b/include/metal/list/partition.hpp @@ -5,6 +5,8 @@ #ifndef METAL_LIST_PARTITION_HPP #define METAL_LIST_PARTITION_HPP +#include + #include #include #include @@ -15,6 +17,8 @@ namespace metal { /// \ingroup list + /// + /// ### Description /// ... template using partition = diff --git a/include/metal/list/push_front.hpp b/include/metal/list/prepend.hpp similarity index 55% rename from include/metal/list/push_front.hpp rename to include/metal/list/prepend.hpp index 892a60eb..a9a3bb33 100644 --- a/include/metal/list/push_front.hpp +++ b/include/metal/list/prepend.hpp @@ -2,8 +2,10 @@ // Distributed under the Boost Software License, Version 1.0. // See accompanying file LICENSE.txt or copy at http://boost.org/LICENSE_1_0.txt -#ifndef METAL_LIST_PUSH_FRONT_HPP -#define METAL_LIST_PUSH_FRONT_HPP +#ifndef METAL_LIST_PREPEND_HPP +#define METAL_LIST_PREPEND_HPP + +#include #include #include @@ -11,9 +13,11 @@ namespace metal { /// \ingroup list + /// + /// ### Description /// ... - template - using push_front = metal::join, seq>; + template + using prepend = metal::join, seq>; } #endif diff --git a/include/metal/list/range.hpp b/include/metal/list/range.hpp index c4e4d5da..0ab5a1cb 100644 --- a/include/metal/list/range.hpp +++ b/include/metal/list/range.hpp @@ -5,12 +5,14 @@ #ifndef METAL_LIST_RANGE_HPP #define METAL_LIST_RANGE_HPP +#include + #include #include -#include -#include +#include +#include #include -#include +#include namespace metal { @@ -18,25 +20,32 @@ namespace metal { template struct _range; + + template + using range = typename detail::_range::type; } /// \ingroup list + /// + /// ### Description /// ... template - using range = typename detail::_range< + using range = detail::range< seq, - if_, beg>, greater>>>, beg>, - if_, end>, greater>>>, end> - >::type; + if_, beg>, size>, beg>, beg>, + if_, end>, size>, end>, end> + >; } #include #include #include #include +#include #include #include +#include namespace metal { @@ -45,79 +54,64 @@ namespace metal template using void_ = void; template - struct _drop_impl + struct _range_impl {}; template - struct _drop_impl, list<_...>> + struct _range_impl, list<_...>> { - template - static list impl(void_<_>*..., value*...); + template + static list impl(void_<_>*..., value*...); using type = decltype(impl(declptr>()...)); }; - template - struct _drop : - _drop_impl, n>> - {}; - - template - using drop = typename _drop::type; - - template - struct _take_impl - {}; - - template - struct _take_impl, list<_...>> : - _join, list<>>...> + template + struct _range : + _range< + range< + range, size>, + number<0>, + sub, min> + >, + sub>, + sub> + > {}; template - struct _take - {}; - - template - struct _take, number> : - _take_impl< - list, + struct _range, n> : + _pick< + seq, join< - enumerate, number, number<0>>, - enumerate, number, number<0>> + enumerate, n, number<0>>, + enumerate, sub, n>, number<0>> > > {}; template - using take = typename _take::type; + struct _range> : + _range_impl, n>> + {}; - template - struct _range_impl + template + struct _range, size> { - using type = list<>; + using type = seq; }; - template - struct _range_impl, number, - number<(e > b)> - > + template + struct _range, number<0>> { - using type = take>, number>; + using type = reverse; }; - template - struct _range_impl, number, - number<(e < b)> - > + template<> + struct _range, number<0>, number<0>> { - using type = reverse>, number>>; + using type = list<>; }; - - template - struct _range : - _range_impl - {}; } } diff --git a/include/metal/list/remove.hpp b/include/metal/list/remove.hpp index a6bc95be..d13f9d1e 100644 --- a/include/metal/list/remove.hpp +++ b/include/metal/list/remove.hpp @@ -5,6 +5,8 @@ #ifndef METAL_LIST_REMOVE_HPP #define METAL_LIST_REMOVE_HPP +#include + #include #include #include @@ -13,6 +15,8 @@ namespace metal { /// \ingroup list + /// + /// ### Description /// ... template using remove = diff --git a/include/metal/list/remove_if.hpp b/include/metal/list/remove_if.hpp index a1ce8bac..9c9878b4 100644 --- a/include/metal/list/remove_if.hpp +++ b/include/metal/list/remove_if.hpp @@ -5,6 +5,8 @@ #ifndef METAL_LIST_REMOVE_IF_HPP #define METAL_LIST_REMOVE_IF_HPP +#include + #include #include #include @@ -13,6 +15,8 @@ namespace metal { /// \ingroup list + /// + /// ### Description /// ... template using remove_if = diff --git a/include/metal/list/replace.hpp b/include/metal/list/replace.hpp index e88ce6e9..b24f0829 100644 --- a/include/metal/list/replace.hpp +++ b/include/metal/list/replace.hpp @@ -5,6 +5,8 @@ #ifndef METAL_LIST_REPLACE_HPP #define METAL_LIST_REPLACE_HPP +#include + #include #include #include @@ -13,6 +15,8 @@ namespace metal { /// \ingroup list + /// + /// ### Description /// ... template using replace = metal::replace_if< diff --git a/include/metal/list/replace_if.hpp b/include/metal/list/replace_if.hpp index 39147e0b..f3d4ff8d 100644 --- a/include/metal/list/replace_if.hpp +++ b/include/metal/list/replace_if.hpp @@ -5,6 +5,8 @@ #ifndef METAL_LIST_REPLACE_IF_HPP #define METAL_LIST_REPLACE_IF_HPP +#include + #include namespace metal @@ -16,6 +18,8 @@ namespace metal } /// \ingroup list + /// + /// ### Description /// ... template using replace_if = diff --git a/include/metal/list/reverse.hpp b/include/metal/list/reverse.hpp index 5f9ece44..d2df0221 100644 --- a/include/metal/list/reverse.hpp +++ b/include/metal/list/reverse.hpp @@ -5,6 +5,8 @@ #ifndef METAL_LIST_REVERSE_HPP #define METAL_LIST_REVERSE_HPP +#include + namespace metal { namespace detail @@ -14,6 +16,8 @@ namespace metal } /// \ingroup list + /// + /// ### Description /// ... template using reverse = typename detail::_reverse::type; @@ -34,41 +38,22 @@ namespace metal typename a, typename b, typename c, typename d, typename e, typename f, typename g, typename h, typename i, typename j, typename k, typename l, - typename m, typename n, typename o, typename p, - typename... tail + typename m, typename n, typename o, typename p, typename... tail > struct _reverse_impl< a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, tail... > : - _join_impl< + _join< typename _reverse_impl::type, list > {}; - template - struct _reverse_impl : - _join_impl::type, list> + template + struct _reverse_impl : + _join::type, list> {}; - template - struct _reverse_impl - { - using type = list; - }; - - template - struct _reverse_impl - { - using type = list; - }; - - template - struct _reverse_impl - { - using type = list; - }; - template<> struct _reverse_impl<> { diff --git a/include/metal/list/size.hpp b/include/metal/list/size.hpp index d98a862a..56cbf867 100644 --- a/include/metal/list/size.hpp +++ b/include/metal/list/size.hpp @@ -5,6 +5,8 @@ #ifndef METAL_LIST_SIZE_HPP #define METAL_LIST_SIZE_HPP +#include + namespace metal { namespace detail @@ -14,6 +16,8 @@ namespace metal } /// \ingroup list + /// + /// ### Description /// ... template using size = typename detail::_size::type; diff --git a/include/metal/list/slice.hpp b/include/metal/list/slice.hpp index 33521c8d..2f75f5e0 100644 --- a/include/metal/list/slice.hpp +++ b/include/metal/list/slice.hpp @@ -5,6 +5,8 @@ #ifndef METAL_LIST_SLICE_HPP #define METAL_LIST_SLICE_HPP +#include + #include #include #include @@ -17,6 +19,8 @@ namespace metal { /// \ingroup list + /// + /// ### Description /// ... template< typename seq, diff --git a/include/metal/list/sort.hpp b/include/metal/list/sort.hpp index a217b6c6..ac8479b6 100644 --- a/include/metal/list/sort.hpp +++ b/include/metal/list/sort.hpp @@ -5,6 +5,8 @@ #ifndef METAL_LIST_SORT_HPP #define METAL_LIST_SORT_HPP +#include + #include #include @@ -14,22 +16,24 @@ namespace metal { template struct _sort; + + template + using sort = typename _sort::type; } /// \ingroup list + /// + /// ### Description /// ... template - using sort = typename detail::_sort, lbd>>::type; + using sort = detail::sort, lbd>>; } #include -#include #include +#include #include -#include -#include #include -#include #include #include @@ -37,73 +41,76 @@ namespace metal { namespace detail { - template - struct _merge; - - template - using merge = typename _merge::type; - - template - using merge_impl = join< - remove_if>, - remove_if>, - merge< - lbd, - copy_if>, - copy_if> - > - >; - - template + template struct _merge {}; template< - typename lbd, + typename ret, typename xh, typename... xt, - typename yh, typename... yt + typename yh, typename... yt, + template class expr > - struct _merge, list> : - _invoke< - lambda, - lbd, list, xh, list, yh + struct _merge, list, lambda, + if_, true_, false_> + > : + _merge< + join>, list, list, lambda > {}; - template - struct _merge> - { - using type = seq; - }; + template< + typename ret, + typename xh, typename... xt, + typename yh, typename... yt, + template class expr + > + struct _merge, list, lambda, + if_, false_, true_> + > : + _merge< + join>, list, list, lambda + > + {}; - template - struct _merge, seq> - { - using type = seq; - }; + template + struct _merge, lbd> : + _join + {}; - template - struct _merge, list<>> + template + struct _merge, seq, lbd> : + _join + {}; + + template + struct _merge, list<>, lbd> { - using type = list<>; + using type = ret; }; template - using sort_impl = merge< - lbd, + using sort_impl = typename _merge< + list<>, sort, div, number<2>>>, lbd>, - sort, number<2>>, size>, lbd> - >; + sort, number<2>>, size>, lbd>, + lbd + >::type; template struct _sort : _invoke, seq, lbd> {}; - template - struct _sort, lbd> + template + struct _sort, lbd> : + _merge, list, list, lbd> + {}; + + template + struct _sort, lbd> { - using type = list; + using type = list; }; template diff --git a/include/metal/list/splice.hpp b/include/metal/list/splice.hpp index 858185bf..3c4e6a9a 100644 --- a/include/metal/list/splice.hpp +++ b/include/metal/list/splice.hpp @@ -5,21 +5,20 @@ #ifndef METAL_LIST_SPLICE_HPP #define METAL_LIST_SPLICE_HPP +#include + #include -#include -#include -#include +#include +#include namespace metal { /// \ingroup list + /// + /// ### Description /// ... template - using splice = metal::join< - metal::range, n>, - other, - metal::range> - >; + using splice = metal::join, other, metal::drop>; } #endif diff --git a/include/metal/list/pop_front.hpp b/include/metal/list/take.hpp similarity index 59% rename from include/metal/list/pop_front.hpp rename to include/metal/list/take.hpp index 5bf87407..547e5374 100644 --- a/include/metal/list/pop_front.hpp +++ b/include/metal/list/take.hpp @@ -2,19 +2,22 @@ // Distributed under the Boost Software License, Version 1.0. // See accompanying file LICENSE.txt or copy at http://boost.org/LICENSE_1_0.txt -#ifndef METAL_LIST_POP_FRONT_HPP -#define METAL_LIST_POP_FRONT_HPP +#ifndef METAL_LIST_TAKE_HPP +#define METAL_LIST_TAKE_HPP + +#include -#include #include #include namespace metal { /// \ingroup list + /// + /// ### Description /// ... - template> - using pop_front = metal::range>; + template + using take = metal::range, n>; } #endif diff --git a/include/metal/list/transform.hpp b/include/metal/list/transform.hpp index 6d1dbd9b..e3e1ce9b 100644 --- a/include/metal/list/transform.hpp +++ b/include/metal/list/transform.hpp @@ -5,6 +5,8 @@ #ifndef METAL_LIST_TRANSFORM_HPP #define METAL_LIST_TRANSFORM_HPP +#include + #include #include #include @@ -16,9 +18,14 @@ namespace metal { template struct _transform; + + template + using transform = typename _transform::type; } /// \ingroup list + /// + /// ### Description /// ... template using transform = typename if_< diff --git a/include/metal/list/transpose.hpp b/include/metal/list/transpose.hpp index 427aa4f3..0b63e0ad 100644 --- a/include/metal/list/transpose.hpp +++ b/include/metal/list/transpose.hpp @@ -5,6 +5,8 @@ #ifndef METAL_LIST_TRANSPOSE_HPP #define METAL_LIST_TRANSPOSE_HPP +#include + #include #include #include @@ -14,6 +16,8 @@ namespace metal { /// \ingroup list + /// + /// ### Description /// ... template using transpose = metal::apply< diff --git a/include/metal/map.hpp b/include/metal/map.hpp index f48e3b54..6f7453b6 100644 --- a/include/metal/map.hpp +++ b/include/metal/map.hpp @@ -5,6 +5,8 @@ #ifndef METAL_MAP_HPP #define METAL_MAP_HPP +#include + #include #include #include diff --git a/include/metal/map/at_key.hpp b/include/metal/map/at_key.hpp index 1b917cf1..92d2406d 100644 --- a/include/metal/map/at_key.hpp +++ b/include/metal/map/at_key.hpp @@ -5,6 +5,8 @@ #ifndef METAL_MAP_AT_KEY_HPP #define METAL_MAP_AT_KEY_HPP +#include + #include #include @@ -13,6 +15,8 @@ namespace metal { /// \ingroup map + /// + /// ### Description /// ... template using at_key = detail::lookup, keys, key>; diff --git a/include/metal/map/erase_key.hpp b/include/metal/map/erase_key.hpp index 0298d8cc..5e1518d0 100644 --- a/include/metal/map/erase_key.hpp +++ b/include/metal/map/erase_key.hpp @@ -5,12 +5,16 @@ #ifndef METAL_MAP_ERASE_KEY_HPP #define METAL_MAP_ERASE_KEY_HPP +#include + #include #include namespace metal { /// \ingroup map + /// + /// ### Description /// ... template using erase_key = metal::erase>; diff --git a/include/metal/map/has_key.hpp b/include/metal/map/has_key.hpp index 6968f264..6ce8243f 100644 --- a/include/metal/map/has_key.hpp +++ b/include/metal/map/has_key.hpp @@ -5,12 +5,16 @@ #ifndef METAL_MAP_HAS_KEY_HPP #define METAL_MAP_HAS_KEY_HPP +#include + #include #include namespace metal { /// \ingroup map + /// + /// ### Description /// ... template using has_key = metal::contains, key>; diff --git a/include/metal/map/keys.hpp b/include/metal/map/keys.hpp index dcd82199..cfc8b3c7 100644 --- a/include/metal/map/keys.hpp +++ b/include/metal/map/keys.hpp @@ -5,6 +5,8 @@ #ifndef METAL_MAP_KEYS_HPP #define METAL_MAP_KEYS_HPP +#include + #include #include #include @@ -14,7 +16,29 @@ namespace metal { /// \ingroup map - /// ... + /// + /// ### Description + /// Returns a \list of keys contained in a \map. + /// + /// ### Usage + /// For any \map `map` + /// \code + /// using result = metal::keys; + /// \endcode + /// + /// \returns: \list + /// \semantics: + /// If `map` associates keys `key_1, ..., key_n` to values + /// `val_1, ..., val_n`, then + /// \code + /// using result = metal::list; + /// \endcode + /// + /// ### Example + /// \snippet map.cpp keys + /// + /// ### See Also + /// \see map, values template using keys = metal::if_< metal::is_map, diff --git a/include/metal/map/map.hpp b/include/metal/map/map.hpp index 9c34d29d..2cd5e12b 100644 --- a/include/metal/map/map.hpp +++ b/include/metal/map/map.hpp @@ -5,6 +5,8 @@ #ifndef METAL_MAP_MAP_HPP #define METAL_MAP_MAP_HPP +#include + #include #include @@ -17,11 +19,15 @@ namespace metal } /// \ingroup map + /// + /// ### Description /// ... template using is_map = typename detail::_is_map::type; /// \ingroup map + /// + /// ### Description /// ... template using map = metal::if_< diff --git a/include/metal/map/order.hpp b/include/metal/map/order.hpp index 696cfea6..1e209ac8 100644 --- a/include/metal/map/order.hpp +++ b/include/metal/map/order.hpp @@ -5,6 +5,8 @@ #ifndef METAL_MAP_ORDER_HPP #define METAL_MAP_ORDER_HPP +#include + #include #include #include @@ -14,6 +16,8 @@ namespace metal { /// \ingroup map + /// + /// ### Description /// ... template using order = metal::at_key< diff --git a/include/metal/map/values.hpp b/include/metal/map/values.hpp index 11201f72..99b50e08 100644 --- a/include/metal/map/values.hpp +++ b/include/metal/map/values.hpp @@ -5,6 +5,8 @@ #ifndef METAL_MAP_VALUES_HPP #define METAL_MAP_VALUES_HPP +#include + #include #include #include @@ -14,7 +16,29 @@ namespace metal { /// \ingroup map - /// ... + /// + /// ### Description + /// Returns a \list of values contained in a \map. + /// + /// ### Usage + /// For any \map `map` + /// \code + /// using result = metal::values; + /// \endcode + /// + /// \returns: \list + /// \semantics: + /// If `map` associates keys `key_1, ..., key_n` to values + /// `val_1, ..., val_n`, then + /// \code + /// using result = metal::list; + /// \endcode + /// + /// ### Example + /// \snippet map.cpp values + /// + /// ### See Also + /// \see map, keys template using values = metal::if_< metal::is_map, diff --git a/include/metal/number.hpp b/include/metal/number.hpp index b2e663c4..6a499d06 100644 --- a/include/metal/number.hpp +++ b/include/metal/number.hpp @@ -5,6 +5,8 @@ #ifndef METAL_NUMBER_HPP #define METAL_NUMBER_HPP +#include + #include #include #include diff --git a/include/metal/number/add.hpp b/include/metal/number/add.hpp index 6542db9a..0dbfa38e 100644 --- a/include/metal/number/add.hpp +++ b/include/metal/number/add.hpp @@ -5,6 +5,8 @@ #ifndef METAL_NUMBER_ADD_HPP #define METAL_NUMBER_ADD_HPP +#include + namespace metal { namespace detail @@ -14,10 +16,11 @@ namespace metal } /// \ingroup number + /// + /// ### Description /// Computes the arithmetic addition of \numbers. /// - /// Usage - /// ----- + /// ### Usage /// For any \numbers `num_1, ..., num_n` /// \code /// using result = metal::add; @@ -29,12 +32,10 @@ namespace metal /// using result = metal::number; /// \endcode /// - /// Example - /// ------- + /// ### Example /// \snippet number.cpp add /// - /// See Also - /// -------- + /// ### See Also /// \see number, inc, dec, neg, sub, mul, div, mod, pow template using add = typename detail::_add::type; @@ -42,8 +43,8 @@ namespace metal #include #include -#include #include +#include #include @@ -65,7 +66,12 @@ namespace metal number {}; -#if __cpp_constexpr >= 201304 +#if defined(METAL_COMPAT_MODE) + template + struct _add, number, number...> : + _fold_left, number, lambda> + {}; +#else template constexpr int_ iadd(int_ head, _... tail) { int_ ret = head; @@ -79,11 +85,7 @@ namespace metal struct _add, number, number...> : number {}; -#else - template - struct _add, number, number...> : - _fold_left, number, lambda> - {}; + #endif } } diff --git a/include/metal/number/and.hpp b/include/metal/number/and.hpp index 431d0f32..66001b49 100644 --- a/include/metal/number/and.hpp +++ b/include/metal/number/and.hpp @@ -5,6 +5,8 @@ #ifndef METAL_NUMBER_AND_HPP #define METAL_NUMBER_AND_HPP +#include + #include #include #include @@ -12,10 +14,11 @@ namespace metal { /// \ingroup number + /// + /// ### Description /// Computes the logical conjunction of \numbers. /// - /// Usage - /// ----- + /// ### Usage /// For any \numbers `num_1, ..., num_n` /// \code /// using result = metal::and_; @@ -27,12 +30,10 @@ namespace metal /// using result = metal::number; /// \endcode /// - /// Example - /// ------- + /// ### Example /// \snippet number.cpp and_ /// - /// See Also - /// -------- + /// ### See Also /// \see number, not_, or_ template using and_ = metal::same...>; diff --git a/include/metal/number/dec.hpp b/include/metal/number/dec.hpp index e772d0ac..b877498a 100644 --- a/include/metal/number/dec.hpp +++ b/include/metal/number/dec.hpp @@ -5,16 +5,19 @@ #ifndef METAL_NUMBER_DEC_HPP #define METAL_NUMBER_DEC_HPP +#include + #include #include namespace metal { /// \ingroup number + /// + /// ### Description /// Decrements a \number. /// - /// Usage - /// ----- + /// ### Usage /// For any \number `num` /// \code /// using result = metal::dec; @@ -26,12 +29,10 @@ namespace metal /// using result = metal::number; /// \endcode /// - /// Example - /// ------- + /// ### Example /// \snippet number.cpp dec /// - /// See Also - /// -------- + /// ### See Also /// \see number, inc, neg, add, sub, mul, div, mod, pow template using dec = metal::sub>; diff --git a/include/metal/number/div.hpp b/include/metal/number/div.hpp index 55fe2c86..ce757ff2 100644 --- a/include/metal/number/div.hpp +++ b/include/metal/number/div.hpp @@ -5,6 +5,8 @@ #ifndef METAL_NUMBER_DIV_HPP #define METAL_NUMBER_DIV_HPP +#include + namespace metal { namespace detail @@ -14,10 +16,11 @@ namespace metal } /// \ingroup number + /// + /// ### Description /// Computes the quotient of the arithmetic division of \numbers. /// - /// Usage - /// ----- + /// ### Usage /// For any \numbers `num_1, ..., num_n` /// \code /// using result = metal::div; @@ -30,12 +33,10 @@ namespace metal /// using result = metal::number; /// \endcode /// - /// Example - /// ------- + /// ### Example /// \snippet number.cpp div /// - /// See Also - /// -------- + /// ### See Also /// \see number, inc, dec, neg, add, sub, mul, mod, pow template using div = typename detail::_div::type; @@ -43,10 +44,9 @@ namespace metal #include #include -#include #include +#include -#include #include namespace metal @@ -71,7 +71,12 @@ namespace metal struct _div, number<0>> {}; -#if __cpp_constexpr >= 201304 +#if defined(METAL_COMPAT_MODE) + template + struct _div, number, number...> : + _fold_left, number, lambda
> + {}; +#else template constexpr int_ idiv(int_ head, _... tail) { int_ ret = head; @@ -86,7 +91,7 @@ namespace metal {}; template - struct _div_impl, + struct _div_impl...>, is_number> >: number @@ -94,12 +99,7 @@ namespace metal template struct _div, number, number...> : - _div_impl> - {}; -#else - template - struct _div, number, number...> : - _fold_left, number, lambda
> + _div_impl> {}; #endif } diff --git a/include/metal/number/enumerate.hpp b/include/metal/number/enumerate.hpp index e564a81d..d16c0684 100644 --- a/include/metal/number/enumerate.hpp +++ b/include/metal/number/enumerate.hpp @@ -5,6 +5,8 @@ #ifndef METAL_NUMBER_ENUMERATE_HPP #define METAL_NUMBER_ENUMERATE_HPP +#include + #include namespace metal @@ -16,10 +18,11 @@ namespace metal } /// \ingroup number + /// + /// ### Description /// Generates a sequence of \numbers. /// - /// Usage - /// ----- + /// ### Usage /// For any \numbers `st`, `sz` and `sd` /// \code /// using result = metal::enumerate; @@ -29,36 +32,26 @@ namespace metal /// \semantics: /// If `sz` is positive, then /// \code - /// using result = metal::list< - /// st, - /// number, - /// number, - /// ..., - /// number, + /// using result = metal::numbers< + /// st{}, st{} + sd{}, ..., st{} + (sz{} - 1)*sd{} /// >; /// \endcode /// otherwise, if `sz` is negative, then /// \code - /// using result = metal::list< - /// st, - /// number, - /// number, - /// ..., - /// number, + /// using result = metal::numbers< + /// st{}, st{} - sd{}, ..., st{} - (1 - sz{})*sd{} /// >; /// \endcode /// otherwise /// \code - /// using result = metal::list<>; + /// using result = metal::numbers<>; /// \endcode /// - /// Example - /// ------- + /// ### Example /// \snippet number.cpp enumerate /// - /// See Also - /// -------- - /// \see number, list + /// ### See Also + /// \see numbers template> using enumerate = typename detail::_enumerate::type; } diff --git a/include/metal/number/greater.hpp b/include/metal/number/greater.hpp index 8372530c..5dc48ff5 100644 --- a/include/metal/number/greater.hpp +++ b/include/metal/number/greater.hpp @@ -5,15 +5,18 @@ #ifndef METAL_NUMBER_GREATER_HPP #define METAL_NUMBER_GREATER_HPP +#include + #include namespace metal { /// \ingroup number + /// + /// ### Description /// Checks whether a \number is greater than another. /// - /// Usage - /// ----- + /// ### Usage /// For any \numbers `num_1` and `num_2` /// \code /// using result = metal::greater; @@ -25,12 +28,10 @@ namespace metal /// using result = metal::number<(num_1{} > num_2{})>; /// \endcode /// - /// Example - /// ------- + /// ### Example /// \snippet number.cpp greater /// - /// See Also - /// -------- + /// ### See Also /// \see number, less template using greater = metal::less; diff --git a/include/metal/number/if.hpp b/include/metal/number/if.hpp index 38cd187c..2aaa6a19 100644 --- a/include/metal/number/if.hpp +++ b/include/metal/number/if.hpp @@ -5,6 +5,8 @@ #ifndef METAL_NUMBER_IF_HPP #define METAL_NUMBER_IF_HPP +#include + namespace metal { namespace detail @@ -14,10 +16,11 @@ namespace metal } /// \ingroup number + /// + /// ### Description /// A multi-clause conditional expression. /// - /// Usage - /// ----- + /// ### Usage /// For any \numbers `num_1, ..., num_n` and \values `val_1, ..., val_n+1` /// \code /// using result = metal::if; @@ -34,12 +37,10 @@ namespace metal /// using result = val_n+1; /// \endcode /// - /// Example - /// ------- + /// ### Example /// \snippet number.cpp if_ /// - /// See Also - /// -------- + /// ### See Also /// \see number template using if_ = typename detail::_if_::type; diff --git a/include/metal/number/inc.hpp b/include/metal/number/inc.hpp index 48ae6088..b45249f4 100644 --- a/include/metal/number/inc.hpp +++ b/include/metal/number/inc.hpp @@ -5,16 +5,19 @@ #ifndef METAL_NUMBER_INC_HPP #define METAL_NUMBER_INC_HPP +#include + #include #include namespace metal { /// \ingroup number + /// + /// ### Description /// Increments a \number. /// - /// Usage - /// ----- + /// ### Usage /// For any \number `num` /// \code /// using result = metal::inc; @@ -26,12 +29,10 @@ namespace metal /// using result = metal::number; /// \endcode /// - /// Example - /// ------- + /// ### Example /// \snippet number.cpp inc /// - /// See Also - /// -------- + /// ### See Also /// \see number, dec, neg, add, sub, mul, div, mod, pow template using inc = metal::add>; diff --git a/include/metal/number/less.hpp b/include/metal/number/less.hpp index 3cfce307..c0b0c511 100644 --- a/include/metal/number/less.hpp +++ b/include/metal/number/less.hpp @@ -5,6 +5,8 @@ #ifndef METAL_NUMBER_LESS_HPP #define METAL_NUMBER_LESS_HPP +#include + namespace metal { namespace detail @@ -14,10 +16,11 @@ namespace metal } /// \ingroup number + /// + /// ### Description /// Checks whether a \number is less than another. /// - /// Usage - /// ----- + /// ### Usage /// For any \numbers `num_1` and `num_2` /// \code /// using result = metal::less; @@ -29,12 +32,10 @@ namespace metal /// using result = metal::number<(num_1{} < num_2{})>; /// \endcode /// - /// Example - /// ------- + /// ### Example /// \snippet number.cpp less /// - /// See Also - /// -------- + /// ### See Also /// \see number, greater template using less = typename detail::_less::type; diff --git a/include/metal/number/max.hpp b/include/metal/number/max.hpp index b2076445..53066c2a 100644 --- a/include/metal/number/max.hpp +++ b/include/metal/number/max.hpp @@ -5,6 +5,8 @@ #ifndef METAL_NUMBER_MAX_HPP #define METAL_NUMBER_MAX_HPP +#include + namespace metal { namespace detail @@ -14,10 +16,11 @@ namespace metal } /// \ingroup number + /// + /// ### Description /// Computes the maximum of \numbers. /// - /// Usage - /// ----- + /// ### Usage /// For any \numbers `num_1, ..., num_n` /// \code /// using result = metal::max; @@ -25,18 +28,15 @@ namespace metal /// /// \returns: \number /// \semantics: - /// If `m` the maximum value between all \numbers in - /// `num_1, ..., num_n`, then + /// If `M` the maximum between all \numbers in `num_1, ..., num_n`, then /// \code - /// using result = metal::number; + /// using result = M; /// \endcode /// - /// Example - /// ------- + /// ### Example /// \snippet number.cpp max /// - /// See Also - /// -------- + /// ### See Also /// \see number, min template using max = typename detail::_max::type; @@ -44,8 +44,8 @@ namespace metal #include #include -#include #include +#include #include @@ -67,7 +67,12 @@ namespace metal number<(x > y) ? x : y> {}; -#if __cpp_constexpr >= 201304 +#if defined(METAL_COMPAT_MODE) + template + struct _max, number, number...> : + _fold_left, number, lambda> + {}; +#else template constexpr int_ imax(int_ head, _... tail) { int_ ret = head; @@ -81,11 +86,6 @@ namespace metal struct _max, number, number...> : number {}; -#else - template - struct _max, number, number...> : - _fold_left, number, lambda> - {}; #endif } } diff --git a/include/metal/number/min.hpp b/include/metal/number/min.hpp index a87821b3..b7899939 100644 --- a/include/metal/number/min.hpp +++ b/include/metal/number/min.hpp @@ -5,6 +5,8 @@ #ifndef METAL_NUMBER_MIN_HPP #define METAL_NUMBER_MIN_HPP +#include + namespace metal { namespace detail @@ -14,10 +16,11 @@ namespace metal } /// \ingroup number + /// + /// ### Description /// Computes the minimum of \numbers. /// - /// Usage - /// ----- + /// ### Usage /// For any \numbers `num_1, ..., num_n` /// \code /// using result = metal::min; @@ -25,18 +28,15 @@ namespace metal /// /// \returns: \number /// \semantics: - /// If `m` the minimum value between all \numbers in - /// `num_1, ..., num_n`, then + /// If `m` the minimum between all \numbers in `num_1, ..., num_n`, then /// \code - /// using result = metal::number; + /// using result = m; /// \endcode /// - /// Example - /// ------- + /// ### Example /// \snippet number.cpp min /// - /// See Also - /// -------- + /// ### See Also /// \see number, max template using min = typename detail::_min::type; @@ -44,8 +44,8 @@ namespace metal #include #include -#include #include +#include #include @@ -67,7 +67,12 @@ namespace metal number<(x < y) ? x : y> {}; -#if __cpp_constexpr >= 201304 +#if defined(METAL_COMPAT_MODE) + template + struct _min, number, number...> : + _fold_left, number, lambda> + {}; +#else template constexpr int_ imin(int_ head, _... tail) { int_ ret = head; @@ -81,11 +86,6 @@ namespace metal struct _min, number, number...> : number {}; -#else - template - struct _min, number, number...> : - _fold_left, number, lambda> - {}; #endif } } diff --git a/include/metal/number/mod.hpp b/include/metal/number/mod.hpp index 0ce9969b..e6a5a467 100644 --- a/include/metal/number/mod.hpp +++ b/include/metal/number/mod.hpp @@ -5,6 +5,8 @@ #ifndef METAL_NUMBER_MOD_HPP #define METAL_NUMBER_MOD_HPP +#include + namespace metal { namespace detail @@ -14,10 +16,11 @@ namespace metal } /// \ingroup number + /// + /// ### Description /// Computes the remainder of the arithmetic division of \numbers. /// - /// Usage - /// ----- + /// ### Usage /// For any \numbers `num_1, ..., num_n` /// \code /// using result = metal::mod; @@ -30,12 +33,10 @@ namespace metal /// using result = metal::number; /// \endcode /// - /// Example - /// ------- + /// ### Example /// \snippet number.cpp mod /// - /// See Also - /// -------- + /// ### See Also /// \see number, inc, dec, neg, add, sub, mul, div, pow template using mod = typename detail::_mod::type; @@ -43,10 +44,9 @@ namespace metal #include #include -#include #include +#include -#include #include namespace metal @@ -71,7 +71,12 @@ namespace metal struct _mod, number<0>> {}; -#if __cpp_constexpr >= 201304 +#if defined(METAL_COMPAT_MODE) + template + struct _mod, number, number...> : + _fold_left, number, lambda> + {}; +#else template constexpr int_ imod(int_ head, _... tail) { int_ ret = head; @@ -86,7 +91,7 @@ namespace metal {}; template - struct _mod_impl, + struct _mod_impl...>, is_number> >: number @@ -94,12 +99,7 @@ namespace metal template struct _mod, number, number...> : - _mod_impl> - {}; -#else - template - struct _mod, number, number...> : - _fold_left, number, lambda> + _mod_impl> {}; #endif } diff --git a/include/metal/number/mul.hpp b/include/metal/number/mul.hpp index 4adf3560..4f7e8679 100644 --- a/include/metal/number/mul.hpp +++ b/include/metal/number/mul.hpp @@ -5,6 +5,8 @@ #ifndef METAL_NUMBER_MUL_HPP #define METAL_NUMBER_MUL_HPP +#include + namespace metal { namespace detail @@ -14,10 +16,11 @@ namespace metal } /// \ingroup number + /// + /// ### Description /// Computes the arithmetic multiplication of \numbers. /// - /// Usage - /// ----- + /// ### Usage /// For any \numbers `num_1, ..., num_n` /// \code /// using result = metal::mul; @@ -29,12 +32,10 @@ namespace metal /// using result = metal::number; /// \endcode /// - /// Example - /// ------- + /// ### Example /// \snippet number.cpp mul /// - /// See Also - /// -------- + /// ### See Also /// \see number, inc, dec, neg, add, sub, div, mod, pow template using mul = typename detail::_mul::type; @@ -42,8 +43,8 @@ namespace metal #include #include -#include #include +#include #include @@ -65,7 +66,12 @@ namespace metal number {}; -#if __cpp_constexpr >= 201304 +#if defined(METAL_COMPAT_MODE) + template + struct _mul, number, number...> : + _fold_left, number, lambda> + {}; +#else template constexpr int_ imul(int_ head, _... tail) { int_ ret = head; @@ -79,11 +85,6 @@ namespace metal struct _mul, number, number...> : number {}; -#else - template - struct _mul, number, number...> : - _fold_left, number, lambda> - {}; #endif } } diff --git a/include/metal/number/neg.hpp b/include/metal/number/neg.hpp index 9152cd00..2e52952e 100644 --- a/include/metal/number/neg.hpp +++ b/include/metal/number/neg.hpp @@ -5,16 +5,19 @@ #ifndef METAL_NUMBER_NEG_HPP #define METAL_NUMBER_NEG_HPP +#include + #include #include namespace metal { /// \ingroup number + /// + /// ### Description /// Computes the additive inverse of a \number. /// - /// Usage - /// ----- + /// ### Usage /// For any \number `num` /// \code /// using result = metal::neg; @@ -26,12 +29,10 @@ namespace metal /// using result = metal::number<-num{}>; /// \endcode /// - /// Example - /// ------- + /// ### Example /// \snippet number.cpp neg /// - /// See Also - /// -------- + /// ### See Also /// \see number, inc, dec, add, sub, mul, div, mod, pow template using neg = metal::sub, num>; diff --git a/include/metal/number/not.hpp b/include/metal/number/not.hpp index c07cc4a9..ecce0542 100644 --- a/include/metal/number/not.hpp +++ b/include/metal/number/not.hpp @@ -5,16 +5,19 @@ #ifndef METAL_NUMBER_NOT_HPP #define METAL_NUMBER_NOT_HPP +#include + #include #include namespace metal { /// \ingroup number - /// Computes the logical negation of a \number. /// - /// Usage - /// ----- + /// ### Description + /// Computes the logical inverse of a \number. + /// + /// ### Usage /// For any \number `num` /// \code /// using result = metal::not_; @@ -23,15 +26,13 @@ namespace metal /// \returns: \number /// \semantics: /// \code - /// using result = metal::number; + /// using result = metal::number; /// \endcode /// - /// Example - /// ------- + /// ### Example /// \snippet number.cpp not_ /// - /// See Also - /// -------- + /// ### See Also /// \see number, and_, or_ template using not_ = metal::if_; diff --git a/include/metal/number/number.hpp b/include/metal/number/number.hpp index 4104b7c7..d902fef2 100644 --- a/include/metal/number/number.hpp +++ b/include/metal/number/number.hpp @@ -5,29 +5,30 @@ #ifndef METAL_NUMBER_NUMBER_HPP #define METAL_NUMBER_NUMBER_HPP +#include + #include #include namespace metal { - /// \ingroup number - /// The underlying integral representation of \numbers. - using int_ = intmax_t; - namespace detail { template struct _is_number; + using int_ = std::intmax_t; + template struct _numbers; } /// \ingroup number + /// + /// ### Description /// Checks whether some \value is a \number. /// - /// Usage - /// ----- + /// ### Usage /// For any \value `val` /// \code /// using result = metal::is_number; @@ -44,32 +45,61 @@ namespace metal /// using result = metal::false_; /// \endcode /// - /// Example - /// ------- + /// ### Example /// \snippet number.cpp is_number /// - /// See Also - /// -------- + /// ### See Also /// \see number, true_, false_ template using is_number = typename detail::_is_number::type; /// \ingroup number + /// + /// ### Description + /// The underlying integral representation of \numbers. + /// + /// ### See Also + /// \see number + using int_ = detail::int_; + + /// \ingroup number + /// + /// ### Description /// Constructs a \number out of an integral value. + /// + /// ### See Also + /// \see int_, is_number template using number = std::integral_constant; /// \ingroup number + /// + /// ### Description /// The boolean constant `true`. + /// + /// ### See Also + /// \see number using true_ = metal::number; /// \ingroup number + /// + /// ### Description /// The boolean constant `false`. + /// + /// ### See Also + /// \see number using false_ = metal::number; /// \ingroup number - /// Constructs a list of \numbers out of a possibly empty sequence of - /// integral values. + /// + /// ### Description + /// Constructs a \list of \numbers out of a sequence of integral values. + /// + /// ### Example + /// \snippet number.cpp numbers + /// + /// ### See Also + /// \see int_, number, list template using numbers = #if defined(METAL_DOXYGENATING) diff --git a/include/metal/number/or.hpp b/include/metal/number/or.hpp index 0431c8ff..25752271 100644 --- a/include/metal/number/or.hpp +++ b/include/metal/number/or.hpp @@ -5,6 +5,8 @@ #ifndef METAL_NUMBER_OR_HPP #define METAL_NUMBER_OR_HPP +#include + #include #include #include @@ -12,10 +14,11 @@ namespace metal { /// \ingroup number + /// + /// ### Description /// Computes the logical disjunction of \numbers. /// - /// Usage - /// ----- + /// ### Usage /// For any \numbers `num_1, ..., num_n` /// \code /// using result = metal::or_; @@ -27,12 +30,10 @@ namespace metal /// using result = metal::number; /// \endcode /// - /// Example - /// ------- + /// ### Example /// \snippet number.cpp or_ /// - /// See Also - /// -------- + /// ### See Also /// \see number, not_, and_ template using or_ = metal::not_...>>; diff --git a/include/metal/number/pow.hpp b/include/metal/number/pow.hpp index 42983130..9e60b539 100644 --- a/include/metal/number/pow.hpp +++ b/include/metal/number/pow.hpp @@ -5,6 +5,8 @@ #ifndef METAL_NUMBER_POW_HPP #define METAL_NUMBER_POW_HPP +#include + namespace metal { namespace detail @@ -14,10 +16,11 @@ namespace metal } /// \ingroup number + /// + /// ### Description /// Computes the arithmetic exponentiation of \numbers. /// - /// Usage - /// ----- + /// ### Usage /// For any \numbers `num_1, ..., num_n` /// \code /// using result = metal::pow; @@ -34,17 +37,15 @@ namespace metal /// Borrowing from Fortran, `x ** y` should be understood as /// `x` raised to the power of `y`. /// } - /// \danger{ + /// \warning{ /// `x ** y` is always null for `y < 0` and `|x| > 1` /// due to inherent limitations of integer arithmetic. /// } /// - /// Example - /// ------- + /// ### Example /// \snippet number.cpp pow /// - /// See Also - /// -------- + /// ### See Also /// \see number, inc, dec, neg, add, sub, mul, div, mod template using pow = typename detail::_pow::type; diff --git a/include/metal/number/sub.hpp b/include/metal/number/sub.hpp index f78bf115..7c7128b6 100644 --- a/include/metal/number/sub.hpp +++ b/include/metal/number/sub.hpp @@ -5,6 +5,8 @@ #ifndef METAL_NUMBER_SUB_HPP #define METAL_NUMBER_SUB_HPP +#include + namespace metal { namespace detail @@ -14,10 +16,11 @@ namespace metal } /// \ingroup number + /// + /// ### Description /// Computes the arithmetic subtraction of \numbers. /// - /// Usage - /// ----- + /// ### Usage /// For any \numbers `num_1, ..., num_n` /// \code /// using result = metal::sub; @@ -29,12 +32,10 @@ namespace metal /// using result = metal::number; /// \endcode /// - /// Example - /// ------- + /// ### Example /// \snippet number.cpp sub /// - /// See Also - /// -------- + /// ### See Also /// \see number, inc, dec, neg, add, mul, div, mod, pow template using sub = typename detail::_sub::type; @@ -42,8 +43,8 @@ namespace metal #include #include -#include #include +#include #include @@ -65,7 +66,12 @@ namespace metal number {}; -#if __cpp_constexpr >= 201304 +#if defined(METAL_COMPAT_MODE) + template + struct _sub, number, number...> : + _fold_left, number, lambda> + {}; +#else template constexpr int_ isub(int_ head, _... tail) { int_ ret = head; @@ -79,11 +85,6 @@ namespace metal struct _sub, number, number...> : number {}; -#else - template - struct _sub, number, number...> : - _fold_left, number, lambda> - {}; #endif } } diff --git a/include/metal/pair.hpp b/include/metal/pair.hpp index 007e019c..d8fd5b88 100644 --- a/include/metal/pair.hpp +++ b/include/metal/pair.hpp @@ -5,6 +5,8 @@ #ifndef METAL_PAIR_HPP #define METAL_PAIR_HPP +#include + #include #include #include diff --git a/include/metal/pair/first.hpp b/include/metal/pair/first.hpp index 6ad4de28..42f7904a 100644 --- a/include/metal/pair/first.hpp +++ b/include/metal/pair/first.hpp @@ -5,6 +5,8 @@ #ifndef METAL_PAIR_FIRST_HPP #define METAL_PAIR_FIRST_HPP +#include + #include #include #include @@ -12,10 +14,11 @@ namespace metal { /// \ingroup pair + /// + /// ### Description /// Returns the first element of a \pair. /// - /// Usage - /// ----- + /// ### Usage /// For any \pair `pair` /// \code /// using result = metal::first; @@ -28,13 +31,11 @@ namespace metal /// using result = x; /// \endcode /// - /// Example - /// ------- + /// ### Example /// \snippet pair.cpp first /// - /// See Also - /// -------- - /// \see pair, second, at + /// ### See Also + /// \see pair, second template using first = metal::if_, metal::front>; } diff --git a/include/metal/pair/pair.hpp b/include/metal/pair/pair.hpp index 8bc7932a..1b09c1f1 100644 --- a/include/metal/pair/pair.hpp +++ b/include/metal/pair/pair.hpp @@ -5,6 +5,8 @@ #ifndef METAL_PAIR_PAIR_HPP #define METAL_PAIR_PAIR_HPP +#include + #include namespace metal @@ -16,16 +18,17 @@ namespace metal } /// \ingroup pair + /// + /// ### Description /// Checks whether some \value is a \pair. /// - /// Usage - /// ----- + /// ### Usage /// For any \value `val` /// \code /// using result = metal::is_pair; /// \endcode /// - /// \returns: \number of type `bool` + /// \returns: \number /// \semantics: /// If `val` is a \pair, then /// \code @@ -36,18 +39,21 @@ namespace metal /// using result = metal::false_; /// \endcode /// - /// Example - /// ------- + /// ### Example /// \snippet pair.cpp is_pair /// - /// See Also - /// -------- + /// ### See Also /// \see pair template using is_pair = typename detail::_is_pair::type; /// \ingroup pair - /// The standard constructor for \pairs. + /// + /// ### Description + /// Constructs a \pair out of a pair of \values. + /// + /// ### See Also + /// \see is_pair template using pair = metal::list; } diff --git a/include/metal/pair/second.hpp b/include/metal/pair/second.hpp index 54fd9b93..e5e08c58 100644 --- a/include/metal/pair/second.hpp +++ b/include/metal/pair/second.hpp @@ -5,6 +5,8 @@ #ifndef METAL_PAIR_SECOND_HPP #define METAL_PAIR_SECOND_HPP +#include + #include #include #include @@ -12,10 +14,11 @@ namespace metal { /// \ingroup pair + /// + /// ### Description /// Returns the second element of a \pair. /// - /// Usage - /// ----- + /// ### Usage /// For any \pair `pair` /// \code /// using result = metal::second; @@ -28,13 +31,11 @@ namespace metal /// using result = y; /// \endcode /// - /// Example - /// ------- + /// ### Example /// \snippet pair.cpp second /// - /// See Also - /// -------- - /// \see pair, first, at + /// ### See Also + /// \see pair, first template using second = metal::if_, metal::back>; } diff --git a/include/metal/value.hpp b/include/metal/value.hpp index e8d4c2f9..9f3c9765 100644 --- a/include/metal/value.hpp +++ b/include/metal/value.hpp @@ -5,6 +5,8 @@ #ifndef METAL_VALUE_HPP #define METAL_VALUE_HPP +#include + #include #include #include diff --git a/include/metal/value/distinct.hpp b/include/metal/value/distinct.hpp index 88b3dfa9..53a996f6 100644 --- a/include/metal/value/distinct.hpp +++ b/include/metal/value/distinct.hpp @@ -5,6 +5,8 @@ #ifndef METAL_VALUE_DISTINCT_HPP #define METAL_VALUE_DISTINCT_HPP +#include + namespace metal { namespace detail @@ -14,7 +16,33 @@ namespace metal } /// \ingroup value - /// ... + /// + /// ### Description + /// Checks whether no \values are identical. + /// + /// ### Usage + /// For any \values `val_1, ..., val_n` + /// \code + /// using result = metal::distinct; + /// \endcode + /// + /// \returns: \number + /// \semantics: + /// If at least two \values in `val_1, ..., val_n` are identical to + /// each other, then + /// \code + /// using result = metal::false_; + /// \endcode + /// otherwise + /// \code + /// using result = metal::true_; + /// \endcode + /// + /// ### Example + /// \snippet value.cpp distinct + /// + /// ### See Also + /// \see same template using distinct = typename detail::_distinct::type; } diff --git a/include/metal/value/same.hpp b/include/metal/value/same.hpp index 7c7d96bf..b9cd5620 100644 --- a/include/metal/value/same.hpp +++ b/include/metal/value/same.hpp @@ -5,6 +5,8 @@ #ifndef METAL_VALUE_SAME_HPP #define METAL_VALUE_SAME_HPP +#include + namespace metal { namespace detail @@ -14,7 +16,33 @@ namespace metal } /// \ingroup value - /// ... + /// + /// ### Description + /// Checks whether \values are identical. + /// + /// ### Usage + /// For any \values `val_1, ..., val_n` + /// \code + /// using result = metal::same; + /// \endcode + /// + /// \returns: \number + /// \semantics: + /// If at least two \values in `val_1, ..., val_n` are not identical to + /// each other, then + /// \code + /// using result = metal::false_; + /// \endcode + /// otherwise + /// \code + /// using result = metal::true_; + /// \endcode + /// + /// ### Example + /// \snippet value.cpp same + /// + /// ### See Also + /// \see distinct template using same = typename detail::_same::type; } diff --git a/include/metal/value/value.hpp b/include/metal/value/value.hpp index d7de1319..b1298784 100644 --- a/include/metal/value/value.hpp +++ b/include/metal/value/value.hpp @@ -5,6 +5,8 @@ #ifndef METAL_VALUE_VALUE_HPP #define METAL_VALUE_VALUE_HPP +#include + #include namespace metal @@ -18,14 +20,91 @@ namespace metal } /// \ingroup value - /// ... + /// + /// ### Description + /// A tautological predicate that checks whether some type is a \value. + /// + /// \tip{Use `metal::is_value` to trigger [SFINAE].} + /// [SFINAE]: http://en.cppreference.com/w/cpp/language/sfinae + /// + /// ### Usage + /// For any \value `val` + /// \code + /// using result = metal::is_value; + /// \endcode + /// + /// \returns: \number + /// \semantics: + /// Equivalent to + /// \code + /// using result = metal::true_; + /// \endcode + /// + /// ### Example + /// \snippet value.cpp is_value + /// + /// ### See Also + /// \see value, nil + template + using is_value = metal::true_; + + /// \ingroup value + /// + /// ### Description + /// Constructs a \value that is guaranteed not to be a \number, or a + /// \lambda or a \list, out of any other \value. + /// + /// The original \value may be retrieved back by naming its nested typename + /// `::type`, unless `metal::value` is [empty](\ref nil), in which case it + /// is undefined. + /// + /// \tip{Use `metal::value` to prevent template pattern matching.} + /// + /// ### Usage + /// For any \value `val` + /// \code + /// using result = metal::value; + /// \endcode + /// + /// \returns: \value + /// \semantics: + /// Equivalent to + /// \code + /// using result = struct {using type = val;}; + /// \endcode + /// + /// ### Example + /// \snippet value.cpp value + /// + /// ### See Also + /// \see is_value, nil template using value = detail::value; /// \ingroup value - /// ... - template - using is_value = metal::true_; + /// + /// ### Description + /// An *empty* `metal::value`. + /// + /// \tip{Use `metal::nil` and `metal::value` to emulate [optionals].} + /// [optionals]: http://en.cppreference.com/w/cpp/utility/optional + /// + /// ### Usage + /// + /// \code + /// using result = metal::nil; + /// \endcode + /// + /// \returns: \value + /// \semantics: + /// Equivalent to + /// \code + /// using result = struct {}; + /// \endcode + /// + /// ### See Also + /// \see is_value, value + using nil = metal::value<>; namespace detail { diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 0cd82f39..e930e258 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -2,7 +2,12 @@ # Distributed under the Boost Software License, Version 1.0. # See accompanying file LICENSE.txt or copy at http://boost.org/LICENSE_1_0.txt +include_directories("${METAL_INCLUDE_DIR}") include_directories("${CMAKE_CURRENT_SOURCE_DIR}/include/") +add_definitions(-DEXPECTED_METAL_MAJOR=${METAL_MAJOR}) +add_definitions(-DEXPECTED_METAL_MINOR=${METAL_MINOR}) +add_definitions(-DEXPECTED_METAL_PATCH=${METAL_PATCH}) + add_custom_target(tests) -metal_add_test_tree(tests "${CMAKE_CURRENT_SOURCE_DIR}/src/") +metal_build_test_tree(tests "${CMAKE_CURRENT_SOURCE_DIR}/src/") diff --git a/test/include/test/preprocessor.hpp b/test/include/test/preprocessor.hpp index 99d4523d..d0f4e174 100644 --- a/test/include/test/preprocessor.hpp +++ b/test/include/test/preprocessor.hpp @@ -185,7 +185,7 @@ #define GEN(M) CAT(CAT(GEN_, INF), J)(INF, M) -#if defined(_MSC_VER) +#if (defined(_MSC_VER) && !defined(__clang__)) # define X_4(...) __VA_ARGS__ # define X_3(...) X_4(__VA_ARGS__) # define X_2(...) X_3(__VA_ARGS__) diff --git a/test/src/metal.cpp b/test/src/metal.cpp index 424a6dd1..73d2f13d 100644 --- a/test/src/metal.cpp +++ b/test/src/metal.cpp @@ -25,13 +25,14 @@ CHECK((metal::flatten>>), (LIST(M))); \ CHECK((metal::flatten, metal::lambda>>), (metal::list)); \ CHECK((metal::at>), (VAL(M))); \ - CHECK((metal::fold_left, metal::lambda>), (metal::fold_right, metal::lambda>)); \ - CHECK((metal::insert), (metal::push_back)); \ - CHECK((metal::insert), (metal::push_front)); \ - CHECK((metal::erase), (metal::pop_back)); \ - CHECK((metal::erase), (metal::pop_front)); \ + CHECK((metal::fold_left, metal::lambda>), (metal::fold_right, metal::lambda>)); \ + CHECK((metal::insert), (metal::append)); \ + CHECK((metal::insert), (metal::prepend)); \ + CHECK((metal::erase), (metal::take)); \ + CHECK((metal::erase), (metal::drop)); \ CHECK((metal::same>), (TRUE)); \ CHECK((metal::slice>), (LIST(M))); \ + CHECK((metal::range, NUM(M), NUM(0)>), (metal::reverse>)); \ CHECK((metal::sort, metal::lambda>), (metal::reverse>)); \ CHECK((metal::transform, metal::quote, metal::_1>, metal::list>), (LIST(M))); \ CHECK((metal::transpose>), (MAP(INC(M)))); \ diff --git a/test/src/metal/config/version.cpp b/test/src/metal/config/version.cpp new file mode 100644 index 00000000..f9642745 --- /dev/null +++ b/test/src/metal/config/version.cpp @@ -0,0 +1,31 @@ +// Copyright Bruno Dutra 2015-2016 +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE.txt or copy at http://boost.org/LICENSE_1_0.txt + +#include + +#if EXPECTED_METAL_MAJOR != METAL_MAJOR +#error major version mismatch! +#endif + +#if EXPECTED_METAL_MINOR != METAL_MINOR +#error minor version mismatch! +#endif + +#if EXPECTED_METAL_PATCH != METAL_PATCH +#error patch version mismatch! +#endif + +#define EXPECTED_METAL_VERSION METAL_SEMVER( \ + EXPECTED_METAL_MAJOR, \ + EXPECTED_METAL_MINOR, \ + EXPECTED_METAL_PATCH \ +) + +#if EXPECTED_METAL_VERSION != METAL_VERSION +#error semantic version mismatch! +#endif + +int main() { + return 0; +} diff --git a/test/src/metal/list/append.cpp b/test/src/metal/list/append.cpp new file mode 100644 index 00000000..4b179ad2 --- /dev/null +++ b/test/src/metal/list/append.cpp @@ -0,0 +1,61 @@ +// Copyright Bruno Dutra 2015-2016 +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE.txt or copy at http://boost.org/LICENSE_1_0.txt + +#include +#include +#include +#include +#include + +#include "test.hpp" + +#define MATRIX(M, N) \ + CHECK((metal::is_invocable, VAL(M) COMMA(N) VALS(N)>), (FALSE)); \ + CHECK((metal::is_invocable, VAL(M) COMMA(N) NUMS(N)>), (FALSE)); \ + CHECK((metal::is_invocable, VAL(M) COMMA(N) PAIRS(N)>), (FALSE)); \ + CHECK((metal::is_invocable, VAL(M) COMMA(N) LISTS(N)>), (FALSE)); \ + CHECK((metal::is_invocable, VAL(M) COMMA(N) MAPS(N)>), (FALSE)); \ + CHECK((metal::is_invocable, VAL(M) COMMA(N) LBDS(N)>), (FALSE)); \ + CHECK((metal::is_invocable, NUM(M) COMMA(N) VALS(N)>), (FALSE)); \ + CHECK((metal::is_invocable, NUM(M) COMMA(N) NUMS(N)>), (FALSE)); \ + CHECK((metal::is_invocable, NUM(M) COMMA(N) PAIRS(N)>), (FALSE)); \ + CHECK((metal::is_invocable, NUM(M) COMMA(N) LISTS(N)>), (FALSE)); \ + CHECK((metal::is_invocable, NUM(M) COMMA(N) MAPS(N)>), (FALSE)); \ + CHECK((metal::is_invocable, NUM(M) COMMA(N) LBDS(N)>), (FALSE)); \ + CHECK((metal::is_invocable, PAIR(M) COMMA(N) VALS(N)>), (BOOL(N > 0))); \ + CHECK((metal::is_invocable, PAIR(M) COMMA(N) NUMS(N)>), (BOOL(N > 0))); \ + CHECK((metal::is_invocable, PAIR(M) COMMA(N) PAIRS(N)>), (BOOL(N > 0))); \ + CHECK((metal::is_invocable, PAIR(M) COMMA(N) LISTS(N)>), (BOOL(N > 0))); \ + CHECK((metal::is_invocable, PAIR(M) COMMA(N) MAPS(N)>), (BOOL(N > 0))); \ + CHECK((metal::is_invocable, PAIR(M) COMMA(N) LBDS(N)>), (BOOL(N > 0))); \ + CHECK((metal::is_invocable, LIST(M) COMMA(N) VALS(N)>), (BOOL(N > 0))); \ + CHECK((metal::is_invocable, LIST(M) COMMA(N) NUMS(N)>), (BOOL(N > 0))); \ + CHECK((metal::is_invocable, LIST(M) COMMA(N) PAIRS(N)>), (BOOL(N > 0))); \ + CHECK((metal::is_invocable, LIST(M) COMMA(N) LISTS(N)>), (BOOL(N > 0))); \ + CHECK((metal::is_invocable, LIST(M) COMMA(N) MAPS(N)>), (BOOL(N > 0))); \ + CHECK((metal::is_invocable, LIST(M) COMMA(N) LBDS(N)>), (BOOL(N > 0))); \ + CHECK((metal::is_invocable, MAP(M) COMMA(N) VALS(N)>), (BOOL(N > 0))); \ + CHECK((metal::is_invocable, MAP(M) COMMA(N) NUMS(N)>), (BOOL(N > 0))); \ + CHECK((metal::is_invocable, MAP(M) COMMA(N) PAIRS(N)>), (BOOL(N > 0))); \ + CHECK((metal::is_invocable, MAP(M) COMMA(N) LISTS(N)>), (BOOL(N > 0))); \ + CHECK((metal::is_invocable, MAP(M) COMMA(N) MAPS(N)>), (BOOL(N > 0))); \ + CHECK((metal::is_invocable, MAP(M) COMMA(N) LBDS(N)>), (BOOL(N > 0))); \ + CHECK((metal::is_invocable, LBD(M) COMMA(N) VALS(N)>), (FALSE)); \ + CHECK((metal::is_invocable, LBD(M) COMMA(N) NUMS(N)>), (FALSE)); \ + CHECK((metal::is_invocable, LBD(M) COMMA(N) PAIRS(N)>), (FALSE)); \ + CHECK((metal::is_invocable, LBD(M) COMMA(N) LISTS(N)>), (FALSE)); \ + CHECK((metal::is_invocable, LBD(M) COMMA(N) MAPS(N)>), (FALSE)); \ + CHECK((metal::is_invocable, LBD(M) COMMA(N) LBDS(N)>), (FALSE)); \ + CHECK((metal::is_invocable, LBD(_) COMMA(N) VALS(N)>), (FALSE)); \ + CHECK((metal::is_invocable, LBD(_) COMMA(N) NUMS(N)>), (FALSE)); \ + CHECK((metal::is_invocable, LBD(_) COMMA(N) PAIRS(N)>), (FALSE)); \ + CHECK((metal::is_invocable, LBD(_) COMMA(N) LISTS(N)>), (FALSE)); \ + CHECK((metal::is_invocable, LBD(_) COMMA(N) MAPS(N)>), (FALSE)); \ + CHECK((metal::is_invocable, LBD(_) COMMA(N) LBDS(N)>), (FALSE)); \ + CHECK((metal::append), (metal::list)); \ + CHECK((metal::append), (metal::list)); \ + CHECK((metal::append), (metal::list)); \ +/**/ + +GEN(MATRIX) diff --git a/test/src/metal/list/drop.cpp b/test/src/metal/list/drop.cpp new file mode 100644 index 00000000..4f12d21e --- /dev/null +++ b/test/src/metal/list/drop.cpp @@ -0,0 +1,59 @@ +// Copyright Bruno Dutra 2015-2016 +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE.txt or copy at http://boost.org/LICENSE_1_0.txt + +#include +#include +#include +#include +#include + +#include "test.hpp" + +#define MATRIX(M, N) \ + CHECK((metal::is_invocable, VAL(M), VAL(N)>), (FALSE)); \ + CHECK((metal::is_invocable, VAL(M), NUM(N)>), (FALSE)); \ + CHECK((metal::is_invocable, VAL(M), PAIR(N)>), (FALSE)); \ + CHECK((metal::is_invocable, VAL(M), LIST(N)>), (FALSE)); \ + CHECK((metal::is_invocable, VAL(M), MAP(N)>), (FALSE)); \ + CHECK((metal::is_invocable, VAL(M), LBD(N)>), (FALSE)); \ + CHECK((metal::is_invocable, VAL(M), LBD(_)>), (FALSE)); \ + CHECK((metal::is_invocable, NUM(M), VAL(N)>), (FALSE)); \ + CHECK((metal::is_invocable, NUM(M), NUM(N)>), (FALSE)); \ + CHECK((metal::is_invocable, NUM(M), PAIR(N)>), (FALSE)); \ + CHECK((metal::is_invocable, NUM(M), LIST(N)>), (FALSE)); \ + CHECK((metal::is_invocable, NUM(M), MAP(N)>), (FALSE)); \ + CHECK((metal::is_invocable, NUM(M), LBD(N)>), (FALSE)); \ + CHECK((metal::is_invocable, NUM(M), LBD(_)>), (FALSE)); \ + CHECK((metal::is_invocable, PAIR(M), VAL(N)>), (FALSE)); \ + CHECK((metal::is_invocable, PAIR(M), NUM(N)>), (BOOL(N < 3))); \ + CHECK((metal::is_invocable, PAIR(M), PAIR(N)>), (FALSE)); \ + CHECK((metal::is_invocable, PAIR(M), LIST(N)>), (FALSE)); \ + CHECK((metal::is_invocable, PAIR(M), MAP(N)>), (FALSE)); \ + CHECK((metal::is_invocable, PAIR(M), LBD(N)>), (FALSE)); \ + CHECK((metal::is_invocable, PAIR(M), LBD(_)>), (FALSE)); \ + CHECK((metal::is_invocable, LIST(M), VAL(N)>), (FALSE)); \ + CHECK((metal::is_invocable, LIST(M), NUM(N)>), (BOOL(M >= N))); \ + CHECK((metal::is_invocable, LIST(M), PAIR(N)>), (FALSE)); \ + CHECK((metal::is_invocable, LIST(M), LIST(N)>), (FALSE)); \ + CHECK((metal::is_invocable, LIST(M), MAP(N)>), (FALSE)); \ + CHECK((metal::is_invocable, LIST(M), LBD(N)>), (FALSE)); \ + CHECK((metal::is_invocable, LIST(M), LBD(_)>), (FALSE)); \ + CHECK((metal::is_invocable, MAP(M), VAL(N)>), (FALSE)); \ + CHECK((metal::is_invocable, MAP(M), NUM(N)>), (BOOL(M >= N))); \ + CHECK((metal::is_invocable, MAP(M), PAIR(N)>), (FALSE)); \ + CHECK((metal::is_invocable, MAP(M), LIST(N)>), (FALSE)); \ + CHECK((metal::is_invocable, MAP(M), MAP(N)>), (FALSE)); \ + CHECK((metal::is_invocable, MAP(M), LBD(N)>), (FALSE)); \ + CHECK((metal::is_invocable, MAP(M), LBD(_)>), (FALSE)); \ + CHECK((metal::is_invocable, LBD(M), VAL(N)>), (FALSE)); \ + CHECK((metal::is_invocable, LBD(M), NUM(N)>), (FALSE)); \ + CHECK((metal::is_invocable, LBD(M), PAIR(N)>), (FALSE)); \ + CHECK((metal::is_invocable, LBD(M), LIST(N)>), (FALSE)); \ + CHECK((metal::is_invocable, LBD(M), MAP(N)>), (FALSE)); \ + CHECK((metal::is_invocable, LBD(M), LBD(N)>), (FALSE)); \ + CHECK((metal::is_invocable, LBD(M), LBD(_)>), (FALSE)); \ + CHECK((metal::drop, NUM(M)>), (LIST(N))); \ +/**/ + +GEN(MATRIX) diff --git a/test/src/metal/list/pop_back.cpp b/test/src/metal/list/pop_back.cpp deleted file mode 100644 index 940a2c82..00000000 --- a/test/src/metal/list/pop_back.cpp +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright Bruno Dutra 2015-2016 -// Distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE.txt or copy at http://boost.org/LICENSE_1_0.txt - -#include -#include -#include -#include -#include - -#include "test.hpp" - -#define MATRIX(M, N) \ - CHECK((metal::is_invocable, VAL(M), VAL(N)>), (FALSE)); \ - CHECK((metal::is_invocable, VAL(M), NUM(N)>), (FALSE)); \ - CHECK((metal::is_invocable, VAL(M), PAIR(N)>), (FALSE)); \ - CHECK((metal::is_invocable, VAL(M), LIST(N)>), (FALSE)); \ - CHECK((metal::is_invocable, VAL(M), MAP(N)>), (FALSE)); \ - CHECK((metal::is_invocable, VAL(M), LBD(N)>), (FALSE)); \ - CHECK((metal::is_invocable, VAL(M), LBD(_)>), (FALSE)); \ - CHECK((metal::is_invocable, NUM(M), VAL(N)>), (FALSE)); \ - CHECK((metal::is_invocable, NUM(M), NUM(N)>), (FALSE)); \ - CHECK((metal::is_invocable, NUM(M), PAIR(N)>), (FALSE)); \ - CHECK((metal::is_invocable, NUM(M), LIST(N)>), (FALSE)); \ - CHECK((metal::is_invocable, NUM(M), MAP(N)>), (FALSE)); \ - CHECK((metal::is_invocable, NUM(M), LBD(N)>), (FALSE)); \ - CHECK((metal::is_invocable, NUM(M), LBD(_)>), (FALSE)); \ - CHECK((metal::is_invocable, PAIR(M), VAL(N)>), (FALSE)); \ - CHECK((metal::is_invocable, PAIR(M), NUM(N)>), (BOOL(N < 3))); \ - CHECK((metal::is_invocable, PAIR(M), PAIR(N)>), (FALSE)); \ - CHECK((metal::is_invocable, PAIR(M), LIST(N)>), (FALSE)); \ - CHECK((metal::is_invocable, PAIR(M), MAP(N)>), (FALSE)); \ - CHECK((metal::is_invocable, PAIR(M), LBD(N)>), (FALSE)); \ - CHECK((metal::is_invocable, PAIR(M), LBD(_)>), (FALSE)); \ - CHECK((metal::is_invocable, LIST(M), VAL(N)>), (FALSE)); \ - CHECK((metal::is_invocable, LIST(M), NUM(N)>), (BOOL(M >= N))); \ - CHECK((metal::is_invocable, LIST(M), PAIR(N)>), (FALSE)); \ - CHECK((metal::is_invocable, LIST(M), LIST(N)>), (FALSE)); \ - CHECK((metal::is_invocable, LIST(M), MAP(N)>), (FALSE)); \ - CHECK((metal::is_invocable, LIST(M), LBD(N)>), (FALSE)); \ - CHECK((metal::is_invocable, LIST(M), LBD(_)>), (FALSE)); \ - CHECK((metal::is_invocable, MAP(M), VAL(N)>), (FALSE)); \ - CHECK((metal::is_invocable, MAP(M), NUM(N)>), (BOOL(M >= N))); \ - CHECK((metal::is_invocable, MAP(M), PAIR(N)>), (FALSE)); \ - CHECK((metal::is_invocable, MAP(M), LIST(N)>), (FALSE)); \ - CHECK((metal::is_invocable, MAP(M), MAP(N)>), (FALSE)); \ - CHECK((metal::is_invocable, MAP(M), LBD(N)>), (FALSE)); \ - CHECK((metal::is_invocable, MAP(M), LBD(_)>), (FALSE)); \ - CHECK((metal::is_invocable, LBD(M), VAL(N)>), (FALSE)); \ - CHECK((metal::is_invocable, LBD(M), NUM(N)>), (FALSE)); \ - CHECK((metal::is_invocable, LBD(M), PAIR(N)>), (FALSE)); \ - CHECK((metal::is_invocable, LBD(M), LIST(N)>), (FALSE)); \ - CHECK((metal::is_invocable, LBD(M), MAP(N)>), (FALSE)); \ - CHECK((metal::is_invocable, LBD(M), LBD(N)>), (FALSE)); \ - CHECK((metal::is_invocable, LBD(M), LBD(_)>), (FALSE)); \ - CHECK((metal::is_invocable, LBD(_), VAL(N)>), (FALSE)); \ - CHECK((metal::is_invocable, LBD(_), NUM(N)>), (FALSE)); \ - CHECK((metal::is_invocable, LBD(_), PAIR(N)>), (FALSE)); \ - CHECK((metal::is_invocable, LBD(_), LIST(N)>), (FALSE)); \ - CHECK((metal::is_invocable, LBD(_), MAP(N)>), (FALSE)); \ - CHECK((metal::is_invocable, LBD(_), LBD(N)>), (FALSE)); \ - CHECK((metal::is_invocable, LBD(_), LBD(_)>), (FALSE)); \ - CHECK((metal::pop_back, NUM(N)>), (LIST(M))); \ -/**/ - -GEN(MATRIX) diff --git a/test/src/metal/list/pop_front.cpp b/test/src/metal/list/pop_front.cpp deleted file mode 100644 index 0e92f8ff..00000000 --- a/test/src/metal/list/pop_front.cpp +++ /dev/null @@ -1,59 +0,0 @@ -// Copyright Bruno Dutra 2015-2016 -// Distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE.txt or copy at http://boost.org/LICENSE_1_0.txt - -#include -#include -#include -#include -#include - -#include "test.hpp" - -#define MATRIX(M, N) \ - CHECK((metal::is_invocable, VAL(M), VAL(N)>), (FALSE)); \ - CHECK((metal::is_invocable, VAL(M), NUM(N)>), (FALSE)); \ - CHECK((metal::is_invocable, VAL(M), PAIR(N)>), (FALSE)); \ - CHECK((metal::is_invocable, VAL(M), LIST(N)>), (FALSE)); \ - CHECK((metal::is_invocable, VAL(M), MAP(N)>), (FALSE)); \ - CHECK((metal::is_invocable, VAL(M), LBD(N)>), (FALSE)); \ - CHECK((metal::is_invocable, VAL(M), LBD(_)>), (FALSE)); \ - CHECK((metal::is_invocable, NUM(M), VAL(N)>), (FALSE)); \ - CHECK((metal::is_invocable, NUM(M), NUM(N)>), (FALSE)); \ - CHECK((metal::is_invocable, NUM(M), PAIR(N)>), (FALSE)); \ - CHECK((metal::is_invocable, NUM(M), LIST(N)>), (FALSE)); \ - CHECK((metal::is_invocable, NUM(M), MAP(N)>), (FALSE)); \ - CHECK((metal::is_invocable, NUM(M), LBD(N)>), (FALSE)); \ - CHECK((metal::is_invocable, NUM(M), LBD(_)>), (FALSE)); \ - CHECK((metal::is_invocable, PAIR(M), VAL(N)>), (FALSE)); \ - CHECK((metal::is_invocable, PAIR(M), NUM(N)>), (BOOL(N < 3))); \ - CHECK((metal::is_invocable, PAIR(M), PAIR(N)>), (FALSE)); \ - CHECK((metal::is_invocable, PAIR(M), LIST(N)>), (FALSE)); \ - CHECK((metal::is_invocable, PAIR(M), MAP(N)>), (FALSE)); \ - CHECK((metal::is_invocable, PAIR(M), LBD(N)>), (FALSE)); \ - CHECK((metal::is_invocable, PAIR(M), LBD(_)>), (FALSE)); \ - CHECK((metal::is_invocable, LIST(M), VAL(N)>), (FALSE)); \ - CHECK((metal::is_invocable, LIST(M), NUM(N)>), (BOOL(M >= N))); \ - CHECK((metal::is_invocable, LIST(M), PAIR(N)>), (FALSE)); \ - CHECK((metal::is_invocable, LIST(M), LIST(N)>), (FALSE)); \ - CHECK((metal::is_invocable, LIST(M), MAP(N)>), (FALSE)); \ - CHECK((metal::is_invocable, LIST(M), LBD(N)>), (FALSE)); \ - CHECK((metal::is_invocable, LIST(M), LBD(_)>), (FALSE)); \ - CHECK((metal::is_invocable, MAP(M), VAL(N)>), (FALSE)); \ - CHECK((metal::is_invocable, MAP(M), NUM(N)>), (BOOL(M >= N))); \ - CHECK((metal::is_invocable, MAP(M), PAIR(N)>), (FALSE)); \ - CHECK((metal::is_invocable, MAP(M), LIST(N)>), (FALSE)); \ - CHECK((metal::is_invocable, MAP(M), MAP(N)>), (FALSE)); \ - CHECK((metal::is_invocable, MAP(M), LBD(N)>), (FALSE)); \ - CHECK((metal::is_invocable, MAP(M), LBD(_)>), (FALSE)); \ - CHECK((metal::is_invocable, LBD(M), VAL(N)>), (FALSE)); \ - CHECK((metal::is_invocable, LBD(M), NUM(N)>), (FALSE)); \ - CHECK((metal::is_invocable, LBD(M), PAIR(N)>), (FALSE)); \ - CHECK((metal::is_invocable, LBD(M), LIST(N)>), (FALSE)); \ - CHECK((metal::is_invocable, LBD(M), MAP(N)>), (FALSE)); \ - CHECK((metal::is_invocable, LBD(M), LBD(N)>), (FALSE)); \ - CHECK((metal::is_invocable, LBD(M), LBD(_)>), (FALSE)); \ - CHECK((metal::pop_front, NUM(M)>), (LIST(N))); \ -/**/ - -GEN(MATRIX) diff --git a/test/src/metal/list/prepend.cpp b/test/src/metal/list/prepend.cpp new file mode 100644 index 00000000..abc4cfa5 --- /dev/null +++ b/test/src/metal/list/prepend.cpp @@ -0,0 +1,61 @@ +// Copyright Bruno Dutra 2015-2016 +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE.txt or copy at http://boost.org/LICENSE_1_0.txt + +#include +#include +#include +#include +#include + +#include "test.hpp" + +#define MATRIX(M, N) \ + CHECK((metal::is_invocable, VAL(M) COMMA(N) VALS(N)>), (FALSE)); \ + CHECK((metal::is_invocable, VAL(M) COMMA(N) NUMS(N)>), (FALSE)); \ + CHECK((metal::is_invocable, VAL(M) COMMA(N) PAIRS(N)>), (FALSE)); \ + CHECK((metal::is_invocable, VAL(M) COMMA(N) LISTS(N)>), (FALSE)); \ + CHECK((metal::is_invocable, VAL(M) COMMA(N) MAPS(N)>), (FALSE)); \ + CHECK((metal::is_invocable, VAL(M) COMMA(N) LBDS(N)>), (FALSE)); \ + CHECK((metal::is_invocable, NUM(M) COMMA(N) VALS(N)>), (FALSE)); \ + CHECK((metal::is_invocable, NUM(M) COMMA(N) NUMS(N)>), (FALSE)); \ + CHECK((metal::is_invocable, NUM(M) COMMA(N) PAIRS(N)>), (FALSE)); \ + CHECK((metal::is_invocable, NUM(M) COMMA(N) LISTS(N)>), (FALSE)); \ + CHECK((metal::is_invocable, NUM(M) COMMA(N) MAPS(N)>), (FALSE)); \ + CHECK((metal::is_invocable, NUM(M) COMMA(N) LBDS(N)>), (FALSE)); \ + CHECK((metal::is_invocable, PAIR(M) COMMA(N) VALS(N)>), (BOOL(N > 0))); \ + CHECK((metal::is_invocable, PAIR(M) COMMA(N) NUMS(N)>), (BOOL(N > 0))); \ + CHECK((metal::is_invocable, PAIR(M) COMMA(N) PAIRS(N)>), (BOOL(N > 0))); \ + CHECK((metal::is_invocable, PAIR(M) COMMA(N) LISTS(N)>), (BOOL(N > 0))); \ + CHECK((metal::is_invocable, PAIR(M) COMMA(N) MAPS(N)>), (BOOL(N > 0))); \ + CHECK((metal::is_invocable, PAIR(M) COMMA(N) LBDS(N)>), (BOOL(N > 0))); \ + CHECK((metal::is_invocable, LIST(M) COMMA(N) VALS(N)>), (BOOL(N > 0))); \ + CHECK((metal::is_invocable, LIST(M) COMMA(N) NUMS(N)>), (BOOL(N > 0))); \ + CHECK((metal::is_invocable, LIST(M) COMMA(N) PAIRS(N)>), (BOOL(N > 0))); \ + CHECK((metal::is_invocable, LIST(M) COMMA(N) LISTS(N)>), (BOOL(N > 0))); \ + CHECK((metal::is_invocable, LIST(M) COMMA(N) MAPS(N)>), (BOOL(N > 0))); \ + CHECK((metal::is_invocable, LIST(M) COMMA(N) LBDS(N)>), (BOOL(N > 0))); \ + CHECK((metal::is_invocable, MAP(M) COMMA(N) VALS(N)>), (BOOL(N > 0))); \ + CHECK((metal::is_invocable, MAP(M) COMMA(N) NUMS(N)>), (BOOL(N > 0))); \ + CHECK((metal::is_invocable, MAP(M) COMMA(N) PAIRS(N)>), (BOOL(N > 0))); \ + CHECK((metal::is_invocable, MAP(M) COMMA(N) LISTS(N)>), (BOOL(N > 0))); \ + CHECK((metal::is_invocable, MAP(M) COMMA(N) MAPS(N)>), (BOOL(N > 0))); \ + CHECK((metal::is_invocable, MAP(M) COMMA(N) LBDS(N)>), (BOOL(N > 0))); \ + CHECK((metal::is_invocable, LBD(M) COMMA(N) VALS(N)>), (FALSE)); \ + CHECK((metal::is_invocable, LBD(M) COMMA(N) NUMS(N)>), (FALSE)); \ + CHECK((metal::is_invocable, LBD(M) COMMA(N) PAIRS(N)>), (FALSE)); \ + CHECK((metal::is_invocable, LBD(M) COMMA(N) LISTS(N)>), (FALSE)); \ + CHECK((metal::is_invocable, LBD(M) COMMA(N) MAPS(N)>), (FALSE)); \ + CHECK((metal::is_invocable, LBD(M) COMMA(N) LBDS(N)>), (FALSE)); \ + CHECK((metal::is_invocable, LBD(_) COMMA(N) VALS(N)>), (FALSE)); \ + CHECK((metal::is_invocable, LBD(_) COMMA(N) NUMS(N)>), (FALSE)); \ + CHECK((metal::is_invocable, LBD(_) COMMA(N) PAIRS(N)>), (FALSE)); \ + CHECK((metal::is_invocable, LBD(_) COMMA(N) LISTS(N)>), (FALSE)); \ + CHECK((metal::is_invocable, LBD(_) COMMA(N) MAPS(N)>), (FALSE)); \ + CHECK((metal::is_invocable, LBD(_) COMMA(N) LBDS(N)>), (FALSE)); \ + CHECK((metal::prepend), (metal::list)); \ + CHECK((metal::prepend), (metal::list)); \ + CHECK((metal::prepend), (metal::list)); \ +/**/ + +GEN(MATRIX) diff --git a/test/src/metal/list/push_back.cpp b/test/src/metal/list/push_back.cpp deleted file mode 100644 index 7f4657d5..00000000 --- a/test/src/metal/list/push_back.cpp +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright Bruno Dutra 2015-2016 -// Distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE.txt or copy at http://boost.org/LICENSE_1_0.txt - -#include -#include -#include -#include -#include - -#include "test.hpp" - -#define MATRIX(M, N) \ - CHECK((metal::is_invocable, VAL(M), VAL(N)>), (FALSE)); \ - CHECK((metal::is_invocable, VAL(M), NUM(N)>), (FALSE)); \ - CHECK((metal::is_invocable, VAL(M), PAIR(N)>), (FALSE)); \ - CHECK((metal::is_invocable, VAL(M), LIST(N)>), (FALSE)); \ - CHECK((metal::is_invocable, VAL(M), MAP(N)>), (FALSE)); \ - CHECK((metal::is_invocable, VAL(M), LBD(N)>), (FALSE)); \ - CHECK((metal::is_invocable, VAL(M), LBD(_)>), (FALSE)); \ - CHECK((metal::is_invocable, NUM(M), VAL(N)>), (FALSE)); \ - CHECK((metal::is_invocable, NUM(M), NUM(N)>), (FALSE)); \ - CHECK((metal::is_invocable, NUM(M), PAIR(N)>), (FALSE)); \ - CHECK((metal::is_invocable, NUM(M), LIST(N)>), (FALSE)); \ - CHECK((metal::is_invocable, NUM(M), MAP(N)>), (FALSE)); \ - CHECK((metal::is_invocable, NUM(M), LBD(N)>), (FALSE)); \ - CHECK((metal::is_invocable, NUM(M), LBD(_)>), (FALSE)); \ - CHECK((metal::is_invocable, PAIR(M), VAL(N)>), (TRUE)); \ - CHECK((metal::is_invocable, PAIR(M), NUM(N)>), (TRUE)); \ - CHECK((metal::is_invocable, PAIR(M), PAIR(N)>), (TRUE)); \ - CHECK((metal::is_invocable, PAIR(M), LIST(N)>), (TRUE)); \ - CHECK((metal::is_invocable, PAIR(M), MAP(N)>), (TRUE)); \ - CHECK((metal::is_invocable, PAIR(M), LBD(N)>), (TRUE)); \ - CHECK((metal::is_invocable, PAIR(M), LBD(_)>), (TRUE)); \ - CHECK((metal::is_invocable, LIST(M), VAL(N)>), (TRUE)); \ - CHECK((metal::is_invocable, LIST(M), NUM(N)>), (TRUE)); \ - CHECK((metal::is_invocable, LIST(M), PAIR(N)>), (TRUE)); \ - CHECK((metal::is_invocable, LIST(M), LIST(N)>), (TRUE)); \ - CHECK((metal::is_invocable, LIST(M), MAP(N)>), (TRUE)); \ - CHECK((metal::is_invocable, LIST(M), LBD(N)>), (TRUE)); \ - CHECK((metal::is_invocable, LIST(M), LBD(_)>), (TRUE)); \ - CHECK((metal::is_invocable, MAP(M), VAL(N)>), (TRUE)); \ - CHECK((metal::is_invocable, MAP(M), NUM(N)>), (TRUE)); \ - CHECK((metal::is_invocable, MAP(M), PAIR(N)>), (TRUE)); \ - CHECK((metal::is_invocable, MAP(M), LIST(N)>), (TRUE)); \ - CHECK((metal::is_invocable, MAP(M), MAP(N)>), (TRUE)); \ - CHECK((metal::is_invocable, MAP(M), LBD(N)>), (TRUE)); \ - CHECK((metal::is_invocable, MAP(M), LBD(_)>), (TRUE)); \ - CHECK((metal::is_invocable, LBD(M), VAL(N)>), (FALSE)); \ - CHECK((metal::is_invocable, LBD(M), NUM(N)>), (FALSE)); \ - CHECK((metal::is_invocable, LBD(M), PAIR(N)>), (FALSE)); \ - CHECK((metal::is_invocable, LBD(M), LIST(N)>), (FALSE)); \ - CHECK((metal::is_invocable, LBD(M), MAP(N)>), (FALSE)); \ - CHECK((metal::is_invocable, LBD(M), LBD(N)>), (FALSE)); \ - CHECK((metal::is_invocable, LBD(M), LBD(_)>), (FALSE)); \ - CHECK((metal::is_invocable, LBD(_), VAL(N)>), (FALSE)); \ - CHECK((metal::is_invocable, LBD(_), NUM(N)>), (FALSE)); \ - CHECK((metal::is_invocable, LBD(_), PAIR(N)>), (FALSE)); \ - CHECK((metal::is_invocable, LBD(_), LIST(N)>), (FALSE)); \ - CHECK((metal::is_invocable, LBD(_), MAP(N)>), (FALSE)); \ - CHECK((metal::is_invocable, LBD(_), LBD(N)>), (FALSE)); \ - CHECK((metal::is_invocable, LBD(_), LBD(_)>), (FALSE)); \ - CHECK((metal::push_back), (metal::list)); \ - CHECK((metal::push_back), (metal::list)); \ - CHECK((metal::push_back), (metal::list)); \ -/**/ - -GEN(MATRIX) diff --git a/test/src/metal/list/push_front.cpp b/test/src/metal/list/push_front.cpp deleted file mode 100644 index be5ae5a3..00000000 --- a/test/src/metal/list/push_front.cpp +++ /dev/null @@ -1,68 +0,0 @@ -// Copyright Bruno Dutra 2015-2016 -// Distributed under the Boost Software License, Version 1.0. -// See accompanying file LICENSE.txt or copy at http://boost.org/LICENSE_1_0.txt - -#include -#include -#include -#include -#include - -#include "test.hpp" - -#define MATRIX(M, N) \ - CHECK((metal::is_invocable, VAL(M), VAL(N)>), (FALSE)); \ - CHECK((metal::is_invocable, VAL(M), NUM(N)>), (FALSE)); \ - CHECK((metal::is_invocable, VAL(M), PAIR(N)>), (FALSE)); \ - CHECK((metal::is_invocable, VAL(M), LIST(N)>), (FALSE)); \ - CHECK((metal::is_invocable, VAL(M), MAP(N)>), (FALSE)); \ - CHECK((metal::is_invocable, VAL(M), LBD(N)>), (FALSE)); \ - CHECK((metal::is_invocable, VAL(M), LBD(_)>), (FALSE)); \ - CHECK((metal::is_invocable, NUM(M), VAL(N)>), (FALSE)); \ - CHECK((metal::is_invocable, NUM(M), NUM(N)>), (FALSE)); \ - CHECK((metal::is_invocable, NUM(M), PAIR(N)>), (FALSE)); \ - CHECK((metal::is_invocable, NUM(M), LIST(N)>), (FALSE)); \ - CHECK((metal::is_invocable, NUM(M), MAP(N)>), (FALSE)); \ - CHECK((metal::is_invocable, NUM(M), LBD(N)>), (FALSE)); \ - CHECK((metal::is_invocable, NUM(M), LBD(_)>), (FALSE)); \ - CHECK((metal::is_invocable, PAIR(M), VAL(N)>), (TRUE)); \ - CHECK((metal::is_invocable, PAIR(M), NUM(N)>), (TRUE)); \ - CHECK((metal::is_invocable, PAIR(M), PAIR(N)>), (TRUE)); \ - CHECK((metal::is_invocable, PAIR(M), LIST(N)>), (TRUE)); \ - CHECK((metal::is_invocable, PAIR(M), MAP(N)>), (TRUE)); \ - CHECK((metal::is_invocable, PAIR(M), LBD(N)>), (TRUE)); \ - CHECK((metal::is_invocable, PAIR(M), LBD(_)>), (TRUE)); \ - CHECK((metal::is_invocable, LIST(M), VAL(N)>), (TRUE)); \ - CHECK((metal::is_invocable, LIST(M), NUM(N)>), (TRUE)); \ - CHECK((metal::is_invocable, LIST(M), PAIR(N)>), (TRUE)); \ - CHECK((metal::is_invocable, LIST(M), LIST(N)>), (TRUE)); \ - CHECK((metal::is_invocable, LIST(M), MAP(N)>), (TRUE)); \ - CHECK((metal::is_invocable, LIST(M), LBD(N)>), (TRUE)); \ - CHECK((metal::is_invocable, LIST(M), LBD(_)>), (TRUE)); \ - CHECK((metal::is_invocable, MAP(M), VAL(N)>), (TRUE)); \ - CHECK((metal::is_invocable, MAP(M), NUM(N)>), (TRUE)); \ - CHECK((metal::is_invocable, MAP(M), PAIR(N)>), (TRUE)); \ - CHECK((metal::is_invocable, MAP(M), LIST(N)>), (TRUE)); \ - CHECK((metal::is_invocable, MAP(M), MAP(N)>), (TRUE)); \ - CHECK((metal::is_invocable, MAP(M), LBD(N)>), (TRUE)); \ - CHECK((metal::is_invocable, MAP(M), LBD(_)>), (TRUE)); \ - CHECK((metal::is_invocable, LBD(M), VAL(N)>), (FALSE)); \ - CHECK((metal::is_invocable, LBD(M), NUM(N)>), (FALSE)); \ - CHECK((metal::is_invocable, LBD(M), PAIR(N)>), (FALSE)); \ - CHECK((metal::is_invocable, LBD(M), LIST(N)>), (FALSE)); \ - CHECK((metal::is_invocable, LBD(M), MAP(N)>), (FALSE)); \ - CHECK((metal::is_invocable, LBD(M), LBD(N)>), (FALSE)); \ - CHECK((metal::is_invocable, LBD(M), LBD(_)>), (FALSE)); \ - CHECK((metal::is_invocable, LBD(_), VAL(N)>), (FALSE)); \ - CHECK((metal::is_invocable, LBD(_), NUM(N)>), (FALSE)); \ - CHECK((metal::is_invocable, LBD(_), PAIR(N)>), (FALSE)); \ - CHECK((metal::is_invocable, LBD(_), LIST(N)>), (FALSE)); \ - CHECK((metal::is_invocable, LBD(_), MAP(N)>), (FALSE)); \ - CHECK((metal::is_invocable, LBD(_), LBD(N)>), (FALSE)); \ - CHECK((metal::is_invocable, LBD(_), LBD(_)>), (FALSE)); \ - CHECK((metal::push_front), (metal::list)); \ - CHECK((metal::push_front), (metal::list)); \ - CHECK((metal::push_front), (metal::list)); \ -/**/ - -GEN(MATRIX) diff --git a/test/src/metal/list/sort.cpp b/test/src/metal/list/sort.cpp index 9c024dcc..57fe69c4 100644 --- a/test/src/metal/list/sort.cpp +++ b/test/src/metal/list/sort.cpp @@ -31,21 +31,21 @@ CHECK((metal::is_invocable, PAIR(M), PAIR(N)>), (FALSE)); \ CHECK((metal::is_invocable, PAIR(M), LIST(N)>), (FALSE)); \ CHECK((metal::is_invocable, PAIR(M), MAP(N)>), (FALSE)); \ - CHECK((metal::is_invocable, PAIR(M), LBD(N)>), (FALSE)); \ + CHECK((metal::is_invocable, PAIR(M), LBD(N)>), (BOOL(N == 2))); \ CHECK((metal::is_invocable, PAIR(M), LBD(_)>), (FALSE)); \ CHECK((metal::is_invocable, LIST(M), VAL(N)>), (FALSE)); \ CHECK((metal::is_invocable, LIST(M), NUM(N)>), (FALSE)); \ CHECK((metal::is_invocable, LIST(M), PAIR(N)>), (FALSE)); \ CHECK((metal::is_invocable, LIST(M), LIST(N)>), (FALSE)); \ CHECK((metal::is_invocable, LIST(M), MAP(N)>), (FALSE)); \ - CHECK((metal::is_invocable, LIST(M), LBD(N)>), (BOOL(M < 2))); \ + CHECK((metal::is_invocable, LIST(M), LBD(N)>), (BOOL(N == 2 || M < 2))); \ CHECK((metal::is_invocable, LIST(M), LBD(_)>), (BOOL(M < 2))); \ CHECK((metal::is_invocable, MAP(M), VAL(N)>), (FALSE)); \ CHECK((metal::is_invocable, MAP(M), NUM(N)>), (FALSE)); \ CHECK((metal::is_invocable, MAP(M), PAIR(N)>), (FALSE)); \ CHECK((metal::is_invocable, MAP(M), LIST(N)>), (FALSE)); \ CHECK((metal::is_invocable, MAP(M), MAP(N)>), (FALSE)); \ - CHECK((metal::is_invocable, MAP(M), LBD(N)>), (BOOL(M < 2))); \ + CHECK((metal::is_invocable, MAP(M), LBD(N)>), (BOOL(N == 2 || M < 2))); \ CHECK((metal::is_invocable, MAP(M), LBD(_)>), (BOOL(M < 2))); \ CHECK((metal::is_invocable, LBD(M), VAL(N)>), (FALSE)); \ CHECK((metal::is_invocable, LBD(M), NUM(N)>), (FALSE)); \ diff --git a/test/src/metal/list/take.cpp b/test/src/metal/list/take.cpp new file mode 100644 index 00000000..fe80c6b7 --- /dev/null +++ b/test/src/metal/list/take.cpp @@ -0,0 +1,66 @@ +// Copyright Bruno Dutra 2015-2016 +// Distributed under the Boost Software License, Version 1.0. +// See accompanying file LICENSE.txt or copy at http://boost.org/LICENSE_1_0.txt + +#include +#include +#include +#include +#include + +#include "test.hpp" + +#define MATRIX(M, N) \ + CHECK((metal::is_invocable, VAL(M), VAL(N)>), (FALSE)); \ + CHECK((metal::is_invocable, VAL(M), NUM(N)>), (FALSE)); \ + CHECK((metal::is_invocable, VAL(M), PAIR(N)>), (FALSE)); \ + CHECK((metal::is_invocable, VAL(M), LIST(N)>), (FALSE)); \ + CHECK((metal::is_invocable, VAL(M), MAP(N)>), (FALSE)); \ + CHECK((metal::is_invocable, VAL(M), LBD(N)>), (FALSE)); \ + CHECK((metal::is_invocable, VAL(M), LBD(_)>), (FALSE)); \ + CHECK((metal::is_invocable, NUM(M), VAL(N)>), (FALSE)); \ + CHECK((metal::is_invocable, NUM(M), NUM(N)>), (FALSE)); \ + CHECK((metal::is_invocable, NUM(M), PAIR(N)>), (FALSE)); \ + CHECK((metal::is_invocable, NUM(M), LIST(N)>), (FALSE)); \ + CHECK((metal::is_invocable, NUM(M), MAP(N)>), (FALSE)); \ + CHECK((metal::is_invocable, NUM(M), LBD(N)>), (FALSE)); \ + CHECK((metal::is_invocable, NUM(M), LBD(_)>), (FALSE)); \ + CHECK((metal::is_invocable, PAIR(M), VAL(N)>), (FALSE)); \ + CHECK((metal::is_invocable, PAIR(M), NUM(N)>), (BOOL(N < 3))); \ + CHECK((metal::is_invocable, PAIR(M), PAIR(N)>), (FALSE)); \ + CHECK((metal::is_invocable, PAIR(M), LIST(N)>), (FALSE)); \ + CHECK((metal::is_invocable, PAIR(M), MAP(N)>), (FALSE)); \ + CHECK((metal::is_invocable, PAIR(M), LBD(N)>), (FALSE)); \ + CHECK((metal::is_invocable, PAIR(M), LBD(_)>), (FALSE)); \ + CHECK((metal::is_invocable, LIST(M), VAL(N)>), (FALSE)); \ + CHECK((metal::is_invocable, LIST(M), NUM(N)>), (BOOL(M >= N))); \ + CHECK((metal::is_invocable, LIST(M), PAIR(N)>), (FALSE)); \ + CHECK((metal::is_invocable, LIST(M), LIST(N)>), (FALSE)); \ + CHECK((metal::is_invocable, LIST(M), MAP(N)>), (FALSE)); \ + CHECK((metal::is_invocable, LIST(M), LBD(N)>), (FALSE)); \ + CHECK((metal::is_invocable, LIST(M), LBD(_)>), (FALSE)); \ + CHECK((metal::is_invocable, MAP(M), VAL(N)>), (FALSE)); \ + CHECK((metal::is_invocable, MAP(M), NUM(N)>), (BOOL(M >= N))); \ + CHECK((metal::is_invocable, MAP(M), PAIR(N)>), (FALSE)); \ + CHECK((metal::is_invocable, MAP(M), LIST(N)>), (FALSE)); \ + CHECK((metal::is_invocable, MAP(M), MAP(N)>), (FALSE)); \ + CHECK((metal::is_invocable, MAP(M), LBD(N)>), (FALSE)); \ + CHECK((metal::is_invocable, MAP(M), LBD(_)>), (FALSE)); \ + CHECK((metal::is_invocable, LBD(M), VAL(N)>), (FALSE)); \ + CHECK((metal::is_invocable, LBD(M), NUM(N)>), (FALSE)); \ + CHECK((metal::is_invocable, LBD(M), PAIR(N)>), (FALSE)); \ + CHECK((metal::is_invocable, LBD(M), LIST(N)>), (FALSE)); \ + CHECK((metal::is_invocable, LBD(M), MAP(N)>), (FALSE)); \ + CHECK((metal::is_invocable, LBD(M), LBD(N)>), (FALSE)); \ + CHECK((metal::is_invocable, LBD(M), LBD(_)>), (FALSE)); \ + CHECK((metal::is_invocable, LBD(_), VAL(N)>), (FALSE)); \ + CHECK((metal::is_invocable, LBD(_), NUM(N)>), (FALSE)); \ + CHECK((metal::is_invocable, LBD(_), PAIR(N)>), (FALSE)); \ + CHECK((metal::is_invocable, LBD(_), LIST(N)>), (FALSE)); \ + CHECK((metal::is_invocable, LBD(_), MAP(N)>), (FALSE)); \ + CHECK((metal::is_invocable, LBD(_), LBD(N)>), (FALSE)); \ + CHECK((metal::is_invocable, LBD(_), LBD(_)>), (FALSE)); \ + CHECK((metal::take, NUM(M)>), (LIST(M))); \ +/**/ + +GEN(MATRIX) diff --git a/test/src/metal/value/value.cpp b/test/src/metal/value/value.cpp index 2dc8dedb..48621816 100644 --- a/test/src/metal/value/value.cpp +++ b/test/src/metal/value/value.cpp @@ -25,6 +25,7 @@ CHECK((metal::is_value), (TRUE)); \ CHECK((metal::is_value), (TRUE)); \ CHECK((metal::is_value), (TRUE)); \ + CHECK((metal::value<>), (metal::nil)); \ /**/ GEN(MATRIX)