@@ -1,4 +1,4 @@ | |||||
# Doxyfile 1.8.14 | |||||
# Doxyfile 1.8.13 | |||||
# This file describes the settings to be used by the documentation system | # This file describes the settings to be used by the documentation system | ||||
# doxygen (www.doxygen.org) for a project. | # doxygen (www.doxygen.org) for a project. | ||||
@@ -20,8 +20,8 @@ | |||||
# This tag specifies the encoding used for all characters in the config file | # This tag specifies the encoding used for all characters in the config file | ||||
# that follow. The default is UTF-8 which is also the encoding used for all text | # that follow. The default is UTF-8 which is also the encoding used for all text | ||||
# before the first occurrence of this tag. Doxygen uses libiconv (or the iconv | # before the first occurrence of this tag. Doxygen uses libiconv (or the iconv | ||||
# built into libc) for the transcoding. See | |||||
# https://www.gnu.org/software/libiconv/ for the list of possible encodings. | |||||
# built into libc) for the transcoding. See http://www.gnu.org/software/libiconv | |||||
# for the list of possible encodings. | |||||
# The default value is: UTF-8. | # The default value is: UTF-8. | ||||
DOXYFILE_ENCODING = UTF-8 | DOXYFILE_ENCODING = UTF-8 | ||||
@@ -58,7 +58,7 @@ PROJECT_LOGO = | |||||
# entered, it will be relative to the location where doxygen was started. If | # entered, it will be relative to the location where doxygen was started. If | ||||
# left blank the current directory will be used. | # left blank the current directory will be used. | ||||
OUTPUT_DIRECTORY = W:\Work\Software\Libraries\utl\doc | |||||
OUTPUT_DIRECTORY = doc | |||||
# If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- | # If the CREATE_SUBDIRS tag is set to YES then doxygen will create 4096 sub- | ||||
# directories (in 2 levels) under the output directory of each output format and | # directories (in 2 levels) under the output directory of each output format and | ||||
@@ -150,7 +150,7 @@ INLINE_INHERITED_MEMB = NO | |||||
# shortest path that makes the file name unique will be used | # shortest path that makes the file name unique will be used | ||||
# The default value is: YES. | # The default value is: YES. | ||||
FULL_PATH_NAMES = YES | |||||
FULL_PATH_NAMES = NO | |||||
# The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. | # The STRIP_FROM_PATH tag can be used to strip a user-defined part of the path. | ||||
# Stripping is only done if one of the specified strings matches the left-hand | # Stripping is only done if one of the specified strings matches the left-hand | ||||
@@ -337,7 +337,7 @@ BUILTIN_STL_SUPPORT = YES | |||||
CPP_CLI_SUPPORT = NO | CPP_CLI_SUPPORT = NO | ||||
# Set the SIP_SUPPORT tag to YES if your project consists of sip (see: | # Set the SIP_SUPPORT tag to YES if your project consists of sip (see: | ||||
# https://www.riverbankcomputing.com/software/sip/intro) sources only. Doxygen | |||||
# http://www.riverbankcomputing.co.uk/software/sip/intro) sources only. Doxygen | |||||
# will parse them like normal C++ but will assume all classes use public instead | # will parse them like normal C++ but will assume all classes use public instead | ||||
# of private inheritance when no explicit protection keyword is present. | # of private inheritance when no explicit protection keyword is present. | ||||
# The default value is: NO. | # The default value is: NO. | ||||
@@ -360,14 +360,14 @@ IDL_PROPERTY_SUPPORT = YES | |||||
# all members of a group must be documented explicitly. | # all members of a group must be documented explicitly. | ||||
# The default value is: NO. | # The default value is: NO. | ||||
DISTRIBUTE_GROUP_DOC = NO | |||||
DISTRIBUTE_GROUP_DOC = YES | |||||
# If one adds a struct or class to a group and this option is enabled, then also | # If one adds a struct or class to a group and this option is enabled, then also | ||||
# any nested class or struct is added to the same group. By default this option | # any nested class or struct is added to the same group. By default this option | ||||
# is disabled and one has to add nested compounds explicitly via \ingroup. | # is disabled and one has to add nested compounds explicitly via \ingroup. | ||||
# The default value is: NO. | # The default value is: NO. | ||||
GROUP_NESTED_COMPOUNDS = NO | |||||
GROUP_NESTED_COMPOUNDS = YES | |||||
# Set the SUBGROUPING tag to YES to allow class member groups of the same type | # Set the SUBGROUPING tag to YES to allow class member groups of the same type | ||||
# (for instance a group of public functions) to be put as a subgroup of that | # (for instance a group of public functions) to be put as a subgroup of that | ||||
@@ -408,7 +408,7 @@ INLINE_SIMPLE_STRUCTS = NO | |||||
# types are typedef'ed and only the typedef is referenced, never the tag name. | # types are typedef'ed and only the typedef is referenced, never the tag name. | ||||
# The default value is: NO. | # The default value is: NO. | ||||
TYPEDEF_HIDES_STRUCT = NO | |||||
TYPEDEF_HIDES_STRUCT = YES | |||||
# The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This | # The size of the symbol lookup cache can be set using LOOKUP_CACHE_SIZE. This | ||||
# cache is used to resolve symbols given their name and scope. Since this can be | # cache is used to resolve symbols given their name and scope. Since this can be | ||||
@@ -435,7 +435,7 @@ LOOKUP_CACHE_SIZE = 0 | |||||
# normally produced when WARNINGS is set to YES. | # normally produced when WARNINGS is set to YES. | ||||
# The default value is: NO. | # The default value is: NO. | ||||
EXTRACT_ALL = YES | |||||
EXTRACT_ALL = NO | |||||
# If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will | # If the EXTRACT_PRIVATE tag is set to YES, all private members of a class will | ||||
# be included in the documentation. | # be included in the documentation. | ||||
@@ -447,7 +447,7 @@ EXTRACT_PRIVATE = YES | |||||
# scope will be included in the documentation. | # scope will be included in the documentation. | ||||
# The default value is: NO. | # The default value is: NO. | ||||
EXTRACT_PACKAGE = YES | |||||
EXTRACT_PACKAGE = NO | |||||
# If the EXTRACT_STATIC tag is set to YES, all static members of a file will be | # If the EXTRACT_STATIC tag is set to YES, all static members of a file will be | ||||
# included in the documentation. | # included in the documentation. | ||||
@@ -469,7 +469,7 @@ EXTRACT_LOCAL_CLASSES = YES | |||||
# included. | # included. | ||||
# The default value is: NO. | # The default value is: NO. | ||||
EXTRACT_LOCAL_METHODS = YES | |||||
EXTRACT_LOCAL_METHODS = NO | |||||
# If this flag is set to YES, the members of anonymous namespaces will be | # If this flag is set to YES, the members of anonymous namespaces will be | ||||
# extracted and appear in the documentation as a namespace called | # extracted and appear in the documentation as a namespace called | ||||
@@ -486,7 +486,7 @@ EXTRACT_ANON_NSPACES = NO | |||||
# section is generated. This option has no effect if EXTRACT_ALL is enabled. | # section is generated. This option has no effect if EXTRACT_ALL is enabled. | ||||
# The default value is: NO. | # The default value is: NO. | ||||
HIDE_UNDOC_MEMBERS = NO | |||||
HIDE_UNDOC_MEMBERS = YES | |||||
# If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all | # If the HIDE_UNDOC_CLASSES tag is set to YES, doxygen will hide all | ||||
# undocumented classes that are normally visible in the class hierarchy. If set | # undocumented classes that are normally visible in the class hierarchy. If set | ||||
@@ -494,7 +494,7 @@ HIDE_UNDOC_MEMBERS = NO | |||||
# has no effect if EXTRACT_ALL is enabled. | # has no effect if EXTRACT_ALL is enabled. | ||||
# The default value is: NO. | # The default value is: NO. | ||||
HIDE_UNDOC_CLASSES = NO | |||||
HIDE_UNDOC_CLASSES = YES | |||||
# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend | # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, doxygen will hide all friend | ||||
# (class|struct|union) declarations. If set to NO, these declarations will be | # (class|struct|union) declarations. If set to NO, these declarations will be | ||||
@@ -508,14 +508,14 @@ HIDE_FRIEND_COMPOUNDS = NO | |||||
# blocks will be appended to the function's detailed documentation block. | # blocks will be appended to the function's detailed documentation block. | ||||
# The default value is: NO. | # The default value is: NO. | ||||
HIDE_IN_BODY_DOCS = NO | |||||
HIDE_IN_BODY_DOCS = YES | |||||
# The INTERNAL_DOCS tag determines if documentation that is typed after a | # The INTERNAL_DOCS tag determines if documentation that is typed after a | ||||
# \internal command is included. If the tag is set to NO then the documentation | # \internal command is included. If the tag is set to NO then the documentation | ||||
# will be excluded. Set it to YES to include the internal documentation. | # will be excluded. Set it to YES to include the internal documentation. | ||||
# The default value is: NO. | # The default value is: NO. | ||||
INTERNAL_DOCS = NO | |||||
INTERNAL_DOCS = YES | |||||
# If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file | # If the CASE_SENSE_NAMES tag is set to NO then doxygen will only generate file | ||||
# names in lower-case letters. If set to YES, upper-case letters are also | # names in lower-case letters. If set to YES, upper-case letters are also | ||||
@@ -570,7 +570,7 @@ INLINE_INFO = YES | |||||
# name. If set to NO, the members will appear in declaration order. | # name. If set to NO, the members will appear in declaration order. | ||||
# The default value is: YES. | # The default value is: YES. | ||||
SORT_MEMBER_DOCS = YES | |||||
SORT_MEMBER_DOCS = NO | |||||
# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief | # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the brief | ||||
# descriptions of file, namespace and class members alphabetically by member | # descriptions of file, namespace and class members alphabetically by member | ||||
@@ -708,7 +708,7 @@ LAYOUT_FILE = | |||||
# The CITE_BIB_FILES tag can be used to specify one or more bib files containing | # The CITE_BIB_FILES tag can be used to specify one or more bib files containing | ||||
# the reference definitions. This must be a list of .bib files. The .bib | # the reference definitions. This must be a list of .bib files. The .bib | ||||
# extension is automatically appended if omitted. This requires the bibtex tool | # extension is automatically appended if omitted. This requires the bibtex tool | ||||
# to be installed. See also https://en.wikipedia.org/wiki/BibTeX for more info. | |||||
# to be installed. See also http://en.wikipedia.org/wiki/BibTeX for more info. | |||||
# For LaTeX the style of the bibliography can be controlled using | # For LaTeX the style of the bibliography can be controlled using | ||||
# LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the | # LATEX_BIB_STYLE. To use this feature you need bibtex and perl available in the | ||||
# search path. See also \cite for info how to create references. | # search path. See also \cite for info how to create references. | ||||
@@ -790,12 +790,12 @@ WARN_LOGFILE = | |||||
# spaces. See also FILE_PATTERNS and EXTENSION_MAPPING | # spaces. See also FILE_PATTERNS and EXTENSION_MAPPING | ||||
# Note: If this tag is empty the current directory is searched. | # Note: If this tag is empty the current directory is searched. | ||||
INPUT = | |||||
INPUT = . | |||||
# This tag can be used to specify the character encoding of the source files | # This tag can be used to specify the character encoding of the source files | ||||
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses | # that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses | ||||
# libiconv (or the iconv built into libc) for the transcoding. See the libiconv | # libiconv (or the iconv built into libc) for the transcoding. See the libiconv | ||||
# documentation (see: https://www.gnu.org/software/libiconv/) for the list of | |||||
# documentation (see: http://www.gnu.org/software/libiconv) for the list of | |||||
# possible encodings. | # possible encodings. | ||||
# The default value is: UTF-8. | # The default value is: UTF-8. | ||||
@@ -873,7 +873,11 @@ RECURSIVE = YES | |||||
# Note that relative paths are relative to the directory from which doxygen is | # Note that relative paths are relative to the directory from which doxygen is | ||||
# run. | # run. | ||||
EXCLUDE = test | |||||
EXCLUDE = test \ | |||||
include/utl/dev \ | |||||
include/utl/concepts \ | |||||
include/utl/com \ | |||||
include/utl/container | |||||
# The EXCLUDE_SYMLINKS tag can be used to select whether or not files or | # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or | ||||
# directories that are symbolic links (a Unix file system feature) are excluded | # directories that are symbolic links (a Unix file system feature) are excluded | ||||
@@ -1043,7 +1047,7 @@ SOURCE_TOOLTIPS = YES | |||||
# If the USE_HTAGS tag is set to YES then the references to source code will | # If the USE_HTAGS tag is set to YES then the references to source code will | ||||
# point to the HTML generated by the htags(1) tool instead of doxygen built-in | # point to the HTML generated by the htags(1) tool instead of doxygen built-in | ||||
# source browser. The htags tool is part of GNU's global source tagging system | # source browser. The htags tool is part of GNU's global source tagging system | ||||
# (see https://www.gnu.org/software/global/global.html). You will need version | |||||
# (see http://www.gnu.org/software/global/global.html). You will need version | |||||
# 4.8.6 or higher. | # 4.8.6 or higher. | ||||
# | # | ||||
# To use it do the following: | # To use it do the following: | ||||
@@ -1079,7 +1083,7 @@ VERBATIM_HEADERS = YES | |||||
# generated with the -Duse-libclang=ON option for CMake. | # generated with the -Duse-libclang=ON option for CMake. | ||||
# The default value is: NO. | # The default value is: NO. | ||||
CLANG_ASSISTED_PARSING = NO | |||||
CLANG_ASSISTED_PARSING = YES | |||||
# If clang assisted parsing is enabled you can provide the compiler with command | # If clang assisted parsing is enabled you can provide the compiler with command | ||||
# line options that you would normally use when invoking the compiler. Note that | # line options that you would normally use when invoking the compiler. Note that | ||||
@@ -1087,18 +1091,7 @@ CLANG_ASSISTED_PARSING = NO | |||||
# specified with INPUT and INCLUDE_PATH. | # specified with INPUT and INCLUDE_PATH. | ||||
# This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES. | # This tag requires that the tag CLANG_ASSISTED_PARSING is set to YES. | ||||
CLANG_OPTIONS = | |||||
# If clang assisted parsing is enabled you can provide the clang parser with the | |||||
# path to the compilation database (see: | |||||
# http://clang.llvm.org/docs/HowToSetupToolingForLLVM.html) used when the files | |||||
# were built. This is equivalent to specifying the "-p" option to a clang tool, | |||||
# such as clang-check. These options will then be pased to the parser. | |||||
# Note: The availability of this option depends on whether or not doxygen was | |||||
# generated with the -Duse-libclang=ON option for CMake. | |||||
# The default value is: 0. | |||||
CLANG_COMPILATION_DATABASE_PATH= 0 | |||||
CLANG_OPTIONS = -std=c++14 | |||||
#--------------------------------------------------------------------------- | #--------------------------------------------------------------------------- | ||||
# Configuration options related to the alphabetical class index | # Configuration options related to the alphabetical class index | ||||
@@ -1218,7 +1211,7 @@ HTML_EXTRA_FILES = | |||||
# The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen | # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. Doxygen | ||||
# will adjust the colors in the style sheet and background images according to | # will adjust the colors in the style sheet and background images according to | ||||
# this color. Hue is specified as an angle on a colorwheel, see | # this color. Hue is specified as an angle on a colorwheel, see | ||||
# https://en.wikipedia.org/wiki/Hue for more information. For instance the value | |||||
# http://en.wikipedia.org/wiki/Hue for more information. For instance the value | |||||
# 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 | # 0 represents red, 60 is yellow, 120 is green, 180 is cyan, 240 is blue, 300 | ||||
# purple, and 360 is red again. | # purple, and 360 is red again. | ||||
# Minimum value: 0, maximum value: 359, default value: 220. | # Minimum value: 0, maximum value: 359, default value: 220. | ||||
@@ -1254,17 +1247,6 @@ HTML_COLORSTYLE_GAMMA = 80 | |||||
HTML_TIMESTAMP = NO | HTML_TIMESTAMP = NO | ||||
# If the HTML_DYNAMIC_MENUS tag is set to YES then the generated HTML | |||||
# documentation will contain a main index with vertical navigation menus that | |||||
# are dynamically created via Javascript. If disabled, the navigation index will | |||||
# consists of multiple levels of tabs that are statically embedded in every HTML | |||||
# page. Disable this option to support browsers that do not have Javascript, | |||||
# like the Qt help browser. | |||||
# The default value is: YES. | |||||
# This tag requires that the tag GENERATE_HTML is set to YES. | |||||
HTML_DYNAMIC_MENUS = YES | |||||
# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML | # 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 | # documentation will contain sections that can be hidden and shown after the | ||||
# page has loaded. | # page has loaded. | ||||
@@ -1288,12 +1270,12 @@ HTML_INDEX_NUM_ENTRIES = 100 | |||||
# If the GENERATE_DOCSET tag is set to YES, additional index files will be | # 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 | # generated that can be used as input for Apple's Xcode 3 integrated development | ||||
# environment (see: https://developer.apple.com/tools/xcode/), introduced with | |||||
# environment (see: http://developer.apple.com/tools/xcode/), introduced with | |||||
# OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a | # OSX 10.5 (Leopard). To create a documentation set, doxygen will generate a | ||||
# Makefile in the HTML output directory. Running make will produce the docset in | # Makefile in the HTML output directory. Running make will produce the docset in | ||||
# that directory and running make install will install the docset in | # that directory and running make install will install the docset in | ||||
# ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at | # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find it at | ||||
# startup. See https://developer.apple.com/tools/creatingdocsetswithdoxygen.html | |||||
# startup. See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html | |||||
# for more information. | # for more information. | ||||
# The default value is: NO. | # The default value is: NO. | ||||
# This tag requires that the tag GENERATE_HTML is set to YES. | # This tag requires that the tag GENERATE_HTML is set to YES. | ||||
@@ -1409,7 +1391,7 @@ QCH_FILE = | |||||
# The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help | # The QHP_NAMESPACE tag specifies the namespace to use when generating Qt Help | ||||
# Project output. For more information please see Qt Help Project / Namespace | # Project output. For more information please see Qt Help Project / Namespace | ||||
# (see: http://doc.qt.io/qt-4.8/qthelpproject.html#namespace). | |||||
# (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#namespace). | |||||
# The default value is: org.doxygen.Project. | # The default value is: org.doxygen.Project. | ||||
# This tag requires that the tag GENERATE_QHP is set to YES. | # This tag requires that the tag GENERATE_QHP is set to YES. | ||||
@@ -1417,7 +1399,8 @@ QHP_NAMESPACE = org.doxygen.Project | |||||
# The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt | # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating Qt | ||||
# Help Project output. For more information please see Qt Help Project / Virtual | # Help Project output. For more information please see Qt Help Project / Virtual | ||||
# Folders (see: http://doc.qt.io/qt-4.8/qthelpproject.html#virtual-folders). | |||||
# Folders (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#virtual- | |||||
# folders). | |||||
# The default value is: doc. | # The default value is: doc. | ||||
# This tag requires that the tag GENERATE_QHP is set to YES. | # This tag requires that the tag GENERATE_QHP is set to YES. | ||||
@@ -1425,21 +1408,23 @@ QHP_VIRTUAL_FOLDER = doc | |||||
# If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom | # If the QHP_CUST_FILTER_NAME tag is set, it specifies the name of a custom | ||||
# filter to add. For more information please see Qt Help Project / Custom | # filter to add. For more information please see Qt Help Project / Custom | ||||
# Filters (see: http://doc.qt.io/qt-4.8/qthelpproject.html#custom-filters). | |||||
# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- | |||||
# filters). | |||||
# This tag requires that the tag GENERATE_QHP is set to YES. | # This tag requires that the tag GENERATE_QHP is set to YES. | ||||
QHP_CUST_FILTER_NAME = | QHP_CUST_FILTER_NAME = | ||||
# The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the | # The QHP_CUST_FILTER_ATTRS tag specifies the list of the attributes of the | ||||
# custom filter to add. For more information please see Qt Help Project / Custom | # custom filter to add. For more information please see Qt Help Project / Custom | ||||
# Filters (see: http://doc.qt.io/qt-4.8/qthelpproject.html#custom-filters). | |||||
# Filters (see: http://qt-project.org/doc/qt-4.8/qthelpproject.html#custom- | |||||
# filters). | |||||
# This tag requires that the tag GENERATE_QHP is set to YES. | # This tag requires that the tag GENERATE_QHP is set to YES. | ||||
QHP_CUST_FILTER_ATTRS = | QHP_CUST_FILTER_ATTRS = | ||||
# The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this | # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this | ||||
# project's filter section matches. Qt Help Project / Filter Attributes (see: | # project's filter section matches. Qt Help Project / Filter Attributes (see: | ||||
# http://doc.qt.io/qt-4.8/qthelpproject.html#filter-attributes). | |||||
# http://qt-project.org/doc/qt-4.8/qthelpproject.html#filter-attributes). | |||||
# This tag requires that the tag GENERATE_QHP is set to YES. | # This tag requires that the tag GENERATE_QHP is set to YES. | ||||
QHP_SECT_FILTER_ATTRS = | QHP_SECT_FILTER_ATTRS = | ||||
@@ -1532,7 +1517,7 @@ EXT_LINKS_IN_WINDOW = NO | |||||
FORMULA_FONTSIZE = 10 | FORMULA_FONTSIZE = 10 | ||||
# Use the FORMULA_TRANSPARENT tag to determine whether or not the images | |||||
# Use the FORMULA_TRANPARENT tag to determine whether or not the images | |||||
# generated for formulas are transparent PNGs. Transparent PNGs are not | # generated for formulas are transparent PNGs. Transparent PNGs are not | ||||
# supported properly for IE 6.0, but are supported on all modern browsers. | # supported properly for IE 6.0, but are supported on all modern browsers. | ||||
# | # | ||||
@@ -1544,7 +1529,7 @@ FORMULA_FONTSIZE = 10 | |||||
FORMULA_TRANSPARENT = YES | FORMULA_TRANSPARENT = YES | ||||
# Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see | # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax (see | ||||
# https://www.mathjax.org) which uses client side Javascript for the rendering | |||||
# http://www.mathjax.org) which uses client side Javascript for the rendering | |||||
# instead of using pre-rendered bitmaps. Use this if you do not have LaTeX | # instead of using pre-rendered bitmaps. Use this if you do not have LaTeX | ||||
# installed or if you want to formulas look prettier in the HTML output. When | # installed or if you want to formulas look prettier in the HTML output. When | ||||
# enabled you may also need to install MathJax separately and configure the path | # enabled you may also need to install MathJax separately and configure the path | ||||
@@ -1571,7 +1556,7 @@ MATHJAX_FORMAT = HTML-CSS | |||||
# MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax | # MATHJAX_RELPATH should be ../mathjax. The default value points to the MathJax | ||||
# Content Delivery Network so you can quickly see the result without installing | # Content Delivery Network so you can quickly see the result without installing | ||||
# MathJax. However, it is strongly recommended to install a local copy of | # MathJax. However, it is strongly recommended to install a local copy of | ||||
# MathJax from https://www.mathjax.org before deployment. | |||||
# MathJax from http://www.mathjax.org before deployment. | |||||
# The default value is: http://cdn.mathjax.org/mathjax/latest. | # The default value is: http://cdn.mathjax.org/mathjax/latest. | ||||
# This tag requires that the tag USE_MATHJAX is set to YES. | # This tag requires that the tag USE_MATHJAX is set to YES. | ||||
@@ -1633,7 +1618,7 @@ SERVER_BASED_SEARCH = NO | |||||
# | # | ||||
# Doxygen ships with an example indexer (doxyindexer) and search engine | # Doxygen ships with an example indexer (doxyindexer) and search engine | ||||
# (doxysearch.cgi) which are based on the open source search engine library | # (doxysearch.cgi) which are based on the open source search engine library | ||||
# Xapian (see: https://xapian.org/). | |||||
# Xapian (see: http://xapian.org/). | |||||
# | # | ||||
# See the section "External Indexing and Searching" for details. | # See the section "External Indexing and Searching" for details. | ||||
# The default value is: NO. | # The default value is: NO. | ||||
@@ -1646,7 +1631,7 @@ EXTERNAL_SEARCH = NO | |||||
# | # | ||||
# Doxygen ships with an example indexer (doxyindexer) and search engine | # Doxygen ships with an example indexer (doxyindexer) and search engine | ||||
# (doxysearch.cgi) which are based on the open source search engine library | # (doxysearch.cgi) which are based on the open source search engine library | ||||
# Xapian (see: https://xapian.org/). See the section "External Indexing and | |||||
# Xapian (see: http://xapian.org/). See the section "External Indexing and | |||||
# Searching" for details. | # Searching" for details. | ||||
# This tag requires that the tag SEARCHENGINE is set to YES. | # This tag requires that the tag SEARCHENGINE is set to YES. | ||||
@@ -1833,7 +1818,7 @@ LATEX_SOURCE_CODE = NO | |||||
# The LATEX_BIB_STYLE tag can be used to specify the style to use for the | # The LATEX_BIB_STYLE tag can be used to specify the style to use for the | ||||
# bibliography, e.g. plainnat, or ieeetr. See | # bibliography, e.g. plainnat, or ieeetr. See | ||||
# https://en.wikipedia.org/wiki/BibTeX and \cite for more info. | |||||
# http://en.wikipedia.org/wiki/BibTeX and \cite for more info. | |||||
# The default value is: plain. | # The default value is: plain. | ||||
# This tag requires that the tag GENERATE_LATEX is set to YES. | # This tag requires that the tag GENERATE_LATEX is set to YES. | ||||
@@ -2016,9 +2001,9 @@ DOCBOOK_PROGRAMLISTING = NO | |||||
#--------------------------------------------------------------------------- | #--------------------------------------------------------------------------- | ||||
# If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an | # If the GENERATE_AUTOGEN_DEF tag is set to YES, doxygen will generate an | ||||
# AutoGen Definitions (see http://autogen.sourceforge.net/) file that captures | |||||
# the structure of the code including all documentation. Note that this feature | |||||
# is still experimental and incomplete at the moment. | |||||
# AutoGen Definitions (see http://autogen.sf.net) file that captures the | |||||
# structure of the code including all documentation. Note that this feature is | |||||
# still experimental and incomplete at the moment. | |||||
# The default value is: NO. | # The default value is: NO. | ||||
GENERATE_AUTOGEN_DEF = NO | GENERATE_AUTOGEN_DEF = NO | ||||
@@ -2231,7 +2216,7 @@ HIDE_UNDOC_RELATIONS = YES | |||||
# http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent | # http://www.graphviz.org/), a graph visualization toolkit from AT&T and Lucent | ||||
# Bell Labs. The other options in this section have no effect if this option is | # Bell Labs. The other options in this section have no effect if this option is | ||||
# set to NO | # set to NO | ||||
# The default value is: NO. | |||||
# The default value is: YES. | |||||
HAVE_DOT = NO | HAVE_DOT = NO | ||||
@@ -2387,7 +2372,9 @@ DIRECTORY_GRAPH = YES | |||||
# Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order | # Note: If you choose svg you need to set HTML_FILE_EXTENSION to xhtml in order | ||||
# to make the SVG files visible in IE 9+ (other browsers do not have this | # to make the SVG files visible in IE 9+ (other browsers do not have this | ||||
# requirement). | # requirement). | ||||
# Possible values are: png, jpg, gif, svg, png:gd, png:gd:gd, png:cairo, | |||||
# Possible values are: png, png:cairo, png:cairo:cairo, png:cairo:gd, png:gd, | |||||
# png:gd:gd, jpg, jpg:cairo, jpg:cairo:gd, jpg:gd, jpg:gd:gd, gif, gif:cairo, | |||||
# gif:cairo:gd, gif:gd, gif:gd:gd, svg, png:gd, png:gd:gd, png:cairo, | |||||
# png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and | # png:cairo:gd, png:cairo:cairo, png:cairo:gdiplus, png:gdiplus and | ||||
# png:gdiplus:gdiplus. | # png:gdiplus:gdiplus. | ||||
# The default value is: png. | # The default value is: png. | ||||
@@ -19,7 +19,7 @@ | |||||
* | * | ||||
*/ | */ | ||||
#ifndef __utl_concepts_concepts_h__ | #ifndef __utl_concepts_concepts_h__ | ||||
#define __utl_consepts_concepts_h__ | |||||
#define __utl_concepts_concepts_h__ | |||||
#include <utl/core/impl.h> | #include <utl/core/impl.h> | ||||
@@ -1,22 +1,6 @@ | |||||
/*! | /*! | ||||
* \file /utl/concepts/stl.h | * \file /utl/concepts/stl.h | ||||
* \brief STL's Concepts | * \brief STL's Concepts | ||||
* | |||||
* Copyright (C) 2018 - 2019 Christos Choutouridis | |||||
* | |||||
* This program is free software: you can redistribute it and/or modify | |||||
* it under the terms of the GNU Lesser General Public License as | |||||
* published by the Free Software Foundation, either version 3 | |||||
* of the License, or (at your option) any later version. | |||||
* | |||||
* This program is distributed in the hope that it will be useful, | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
* GNU Lesser General Public License for more details. | |||||
* | |||||
* You should have received a copy of the GNU Lesser General Public License | |||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||||
* | |||||
*/ | */ | ||||
#ifndef __utl_concepts_stl_h__ | #ifndef __utl_concepts_stl_h__ | ||||
#define __utl_concepts_stl_h__ | #define __utl_concepts_stl_h__ | ||||
@@ -1,22 +1,6 @@ | |||||
/*! | /*! | ||||
* \file /utl/impl/crtp.h | |||||
* \file utl/core/crtp.h | |||||
* \brief CRTP idiom support header | * \brief CRTP idiom support header | ||||
* | |||||
* Copyright (C) 2018 Christos Choutouridis | |||||
* | |||||
* This program is free software: you can redistribute it and/or modify | |||||
* it under the terms of the GNU Lesser General Public License as | |||||
* published by the Free Software Foundation, either version 3 | |||||
* of the License, or (at your option) any later version. | |||||
* | |||||
* This program is distributed in the hope that it will be useful, | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
* GNU Lesser General Public License for more details. | |||||
* | |||||
* You should have received a copy of the GNU Lesser General Public License | |||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||||
* | |||||
*/ | */ | ||||
#ifndef __utl_impl_crtp_h__ | #ifndef __utl_impl_crtp_h__ | ||||
#define __utl_impl_crtp_h__ | #define __utl_impl_crtp_h__ | ||||
@@ -25,12 +9,14 @@ | |||||
/*! | /*! | ||||
* \defgroup crtp CRTP idiom support header | * \defgroup crtp CRTP idiom support header | ||||
* \ingroup impl | |||||
* \ingroup core | |||||
* | * | ||||
* utl supports both CRTP idiom and dynamic polymorphism. By default | * utl supports both CRTP idiom and dynamic polymorphism. By default | ||||
* CRTP is the preferred way. If the user need virtuals then instead of | * CRTP is the preferred way. If the user need virtuals then instead of | ||||
* CRTP type, the \ref virtual_tag can passed to base class. The rest | |||||
* CRTP type, the \c virtual_tag can passed to base class. The rest | |||||
* will handled by utl automatically. | * will handled by utl automatically. | ||||
* | |||||
* \sa utl::virtual_tag | |||||
*/ | */ | ||||
//!@{ | //!@{ | ||||
namespace utl { | namespace utl { | ||||
@@ -41,8 +27,8 @@ namespace utl { | |||||
//! \def CRTP boilerplate lines | //! \def CRTP boilerplate lines | ||||
#define _CRTP_IMPL(T) \ | #define _CRTP_IMPL(T) \ | ||||
constexpr T& impl() { return *static_cast<T*>(this); } \ | |||||
constexpr const T& impl() const { return *static_cast<const T*>(this); } | |||||
constexpr T& impl() { return *static_cast<T*>(this); } \ | |||||
constexpr const T& impl() const { return *static_cast<const T*>(this); } | |||||
} | } | ||||
//!@} | //!@} | ||||
@@ -1,30 +1,18 @@ | |||||
/*! | /*! | ||||
* \file /utl/core/impl.h | |||||
* \file utl/core/impl.h | |||||
* \brief Implementation detail main forward header | * \brief Implementation detail main forward header | ||||
* | |||||
* Copyright (C) 2018 Christos Choutouridis | |||||
* | |||||
* This program is free software: you can redistribute it and/or modify | |||||
* it under the terms of the GNU Lesser General Public License as | |||||
* published by the Free Software Foundation, either version 3 | |||||
* of the License, or (at your option) any later version. | |||||
* | |||||
* This program is distributed in the hope that it will be useful, | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
* GNU Lesser General Public License for more details. | |||||
* | |||||
* You should have received a copy of the GNU Lesser General Public License | |||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||||
* | |||||
*/ | */ | ||||
#ifndef __utl_core_impl_h__ | #ifndef __utl_core_impl_h__ | ||||
#define __utl_core_impl_h__ | #define __utl_core_impl_h__ | ||||
//! \defgroup core Core | |||||
//! Provide compiler feature support macros, uTL version, | |||||
//! global types etc... | |||||
// FWD include implementation details once | // FWD include implementation details once | ||||
#include <utl/core/version.h> | #include <utl/core/version.h> | ||||
#include <utl/core/types.h> | #include <utl/core/types.h> | ||||
#include <utl/core/crtp.h> | |||||
#endif /* __utl_core_impl_h__ */ | #endif /* __utl_core_impl_h__ */ |
@@ -1,23 +1,8 @@ | |||||
/*! | /*! | ||||
* \file /utl/core/types.h | |||||
* \file utl/core/types.h | |||||
* \brief Basic type alias support | * \brief Basic type alias support | ||||
* | |||||
* Copyright (C) 2018 Christos Choutouridis | |||||
* | |||||
* This program is free software: you can redistribute it and/or modify | |||||
* it under the terms of the GNU Lesser General Public License as | |||||
* published by the Free Software Foundation, either version 3 | |||||
* of the License, or (at your option) any later version. | |||||
* | |||||
* This program is distributed in the hope that it will be useful, | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
* GNU Lesser General Public License for more details. | |||||
* | |||||
* You should have received a copy of the GNU Lesser General Public License | |||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||||
* | |||||
*/ | */ | ||||
#ifndef __utl_core_types_h__ | #ifndef __utl_core_types_h__ | ||||
#define __utl_core_types_h__ | #define __utl_core_types_h__ | ||||
@@ -27,13 +12,15 @@ | |||||
//#include <type_traits> | //#include <type_traits> | ||||
namespace utl { | namespace utl { | ||||
//! @{ \name byte and word types | |||||
//! \name byte and word types | |||||
//! @{ | |||||
using byte_t = uint8_t; //!< 8 bits wide | using byte_t = uint8_t; //!< 8 bits wide | ||||
using word_t = uint16_t; //!< 16 bits wide | using word_t = uint16_t; //!< 16 bits wide | ||||
using dword_t = uint32_t; //!< 32 bits wide | using dword_t = uint32_t; //!< 32 bits wide | ||||
//! @} | //! @} | ||||
//! @{ \name size and index | |||||
//! \name size and index | |||||
//! @{ | |||||
using size_t = std::size_t; | using size_t = std::size_t; | ||||
using index_t = size_t; //!< index_t and size_t mend to be interchangeable | using index_t = size_t; //!< index_t and size_t mend to be interchangeable | ||||
@@ -1,46 +1,44 @@ | |||||
/*! | /*! | ||||
* \file /utl/core/version.h | |||||
* \brief version and cpp version checks | |||||
* | |||||
* Copyright (C) 2018-2019 Christos Choutouridis | |||||
* | |||||
* This program is free software: you can redistribute it and/or modify | |||||
* it under the terms of the GNU Lesser General Public License as | |||||
* published by the Free Software Foundation, either version 3 | |||||
* of the License, or (at your option) any later version. | |||||
* | |||||
* This program is distributed in the hope that it will be useful, | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
* GNU Lesser General Public License for more details. | |||||
* | |||||
* You should have received a copy of the GNU Lesser General Public License | |||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||||
* | |||||
* \file utl/core/version.h | |||||
* \brief utl version and cpp version checks | |||||
*/ | */ | ||||
#ifndef __utl_core_version_h__ | #ifndef __utl_core_version_h__ | ||||
#define __utl_core_version_h__ | #define __utl_core_version_h__ | ||||
//!\defgroup version version | |||||
//! Definitions of the utl version | |||||
//!\addtogroup core | |||||
//! @{ | |||||
//! \defgroup version Version | |||||
//! Definitions of the utl version and compiler features | |||||
//!@{ | //!@{ | ||||
//! utl version | |||||
//! utl version as string | |||||
#define UTL_VERSION "0.1.0" | #define UTL_VERSION "0.1.0" | ||||
#define UTL_VERSION_MAJOR 0 | #define UTL_VERSION_MAJOR 0 | ||||
#define UTL_VERSION_MINOR 1 | #define UTL_VERSION_MINOR 1 | ||||
#define UTL_VERSION_PATCH 0 | #define UTL_VERSION_PATCH 0 | ||||
//! utl version as integer | |||||
//! | |||||
//! This can be used in the user files to check for uTL versions. | |||||
//! The version number is constructed using:\n | |||||
//! \f$ ver = (Maj*10000 + Min*100 + Patch) \f$ | |||||
#define UTL_VERSION_VALUE ( (UTL_VERSION_MAJOR * 10000) \ | #define UTL_VERSION_VALUE ( (UTL_VERSION_MAJOR * 10000) \ | ||||
+ (UTL_VERSION_MINOR * 100) \ | + (UTL_VERSION_MINOR * 100) \ | ||||
+ UTL_VERSION_PATCH) | + UTL_VERSION_PATCH) | ||||
//! C++ versions | |||||
#define CXX_VER __cplusplus | |||||
#define CXX_VER_STD_11 201103L | |||||
#define CXX_VER_STD_14 201402L | |||||
#define CXX_VER_STD_17 201703L | |||||
//!@} | |||||
//! \name Compiler and feature checks | |||||
//! These checks are used inside uTL, but the user is free to use the as well. | |||||
//! @{ | |||||
#define CXX_VER __cplusplus //!< Current compiler's version | |||||
#define CXX_VER_STD_11 201103L //!< C++11 | |||||
#define CXX_VER_STD_14 201402L //!< C++14 | |||||
#define CXX_VER_STD_17 201703L //!< C++17 | |||||
//! Check for variable templates | |||||
//! \def CXX_VARIABLE_TEMPLATES | |||||
//! Check for variable templates (Non-zero if available) | |||||
#ifndef CXX_VARIABLE_TEMPLATES | #ifndef CXX_VARIABLE_TEMPLATES | ||||
#ifdef __cpp_variable_templates | #ifdef __cpp_variable_templates | ||||
#define CXX_VARIABLE_TEMPLATES __cpp_variable_templates | #define CXX_VARIABLE_TEMPLATES __cpp_variable_templates | ||||
@@ -49,7 +47,8 @@ | |||||
#endif | #endif | ||||
#endif | #endif | ||||
//! Check concepts | |||||
//! \def CXX_CONCEPTS | |||||
//! Check for concepts (Non-zero if available) | |||||
#ifndef CXX_CONCEPTS | #ifndef CXX_CONCEPTS | ||||
#ifdef __cpp_concepts | #ifdef __cpp_concepts | ||||
#define CXX_CONCEPTS __cpp_concepts | #define CXX_CONCEPTS __cpp_concepts | ||||
@@ -58,7 +57,8 @@ | |||||
#endif | #endif | ||||
#endif | #endif | ||||
//! Check for inline variables | |||||
//! \def CXX_INLINE_VARIABLES | |||||
//! Check for inline variables (Non-zero if available) | |||||
#ifndef CXX_INLINE_VARIABLES | #ifndef CXX_INLINE_VARIABLES | ||||
#ifdef __cpp_inline_variables | #ifdef __cpp_inline_variables | ||||
#define CXX_INLINE_VARIABLES __cpp_inline_variables | #define CXX_INLINE_VARIABLES __cpp_inline_variables | ||||
@@ -67,6 +67,8 @@ | |||||
#endif | #endif | ||||
#endif | #endif | ||||
//! \def CXX_FOLD_EXPRESSIONS | |||||
//! Check for fold expressions (Non-zero if available) | |||||
#ifndef CXX_FOLD_EXPRESSIONS | #ifndef CXX_FOLD_EXPRESSIONS | ||||
#ifdef __cpp_fold_expressions | #ifdef __cpp_fold_expressions | ||||
#define CXX_FOLD_EXPRESSIONS __cpp_fold_expressions | #define CXX_FOLD_EXPRESSIONS __cpp_fold_expressions | ||||
@@ -75,19 +77,23 @@ | |||||
#endif | #endif | ||||
#endif | #endif | ||||
/* | |||||
* Workaround inspections | |||||
*/ | |||||
//! @} | |||||
//! \name Workaround inspections | |||||
//! @{ | |||||
#if defined(__GNUC__) && (__GNUC__ < 5) | #if defined(__GNUC__) && (__GNUC__ < 5) | ||||
// https://wg21.link/cwg1558 | // https://wg21.link/cwg1558 | ||||
#define UTL_WORKAROUND_CWG_1558 | #define UTL_WORKAROUND_CWG_1558 | ||||
#endif | #endif | ||||
//! Base library requirement | //! Base library requirement | ||||
#if CXX_VER < CXX_VER_STD_14 | #if CXX_VER < CXX_VER_STD_14 | ||||
#error "uTL requires C++14" | #error "uTL requires C++14" | ||||
#endif | #endif | ||||
//!@} | |||||
//! @} | |||||
//! @} | |||||
#endif /* #ifndef __utl_core_version_h__ */ | #endif /* #ifndef __utl_core_version_h__ */ |
@@ -23,6 +23,7 @@ | |||||
#include <utl/core/impl.h> | #include <utl/core/impl.h> | ||||
#include <utl/meta/meta.h> | #include <utl/meta/meta.h> | ||||
#include <iterator> | |||||
namespace utl { | namespace utl { | ||||
@@ -0,0 +1,415 @@ | |||||
/*! | |||||
* \file utl/meta/basic.h | |||||
* \brief Template meta-programming basic definitions | |||||
*/ | |||||
#ifndef __utl_meta_basic_h__ | |||||
#define __utl_meta_basic_h__ | |||||
#include <utl/core/impl.h> | |||||
#include <type_traits> | |||||
#include <utility> | |||||
/*! | |||||
* \ingroup meta | |||||
* \defgroup basic Basic | |||||
* Basic definitions | |||||
*/ | |||||
//! @{ | |||||
/*! | |||||
* \ingroup basic | |||||
* \defgroup meta_core Core | |||||
* Core definitions | |||||
*/ | |||||
//! @{ | |||||
namespace utl { | |||||
namespace meta { | |||||
/*! | |||||
* \brief meta's empty type | |||||
* | |||||
* utl::meta's nil type is not pure nil. It's a recursive "de-referencable nil. | |||||
* Each time someone applies \c \::type to it, he gets back nil_. This way we can prevent | |||||
* a lot of compilation errors in a wrong meta:: handling. | |||||
*/ | |||||
struct nil_ { | |||||
using type = nil_; | |||||
}; | |||||
//! Type alias for \c Tp::type. | |||||
//! Is used to evaluate/extract return type of metafunctions | |||||
//! \tparam Tp The metafunction to evaluate | |||||
//! \return The inner \::type | |||||
template <typename Tp> | |||||
using eval = typename Tp::type; | |||||
//! Type alias for \c Tp::type::value. | |||||
//! Is used to evaluate/extract return value of metafunctions | |||||
//! \tparam Tp The metafunction to evaluate | |||||
//! \return The inner \::type::value | |||||
template <typename Tp> | |||||
using eval_v = typename eval<Tp>::value; | |||||
//! | |||||
//! integral_ is a holder class for a compile-time value of an integral type. | |||||
//! | |||||
//! Every Integral Constant is also a null-ary Metafunction, returning itself.\n | |||||
//! An integral constant object is implicitly convertible to the corresponding | |||||
//! run-time value of the wrapped integral type | |||||
template <typename Tp, Tp v> | |||||
using integral_ = std::integral_constant<Tp, v>; | |||||
//! \name Wrappers for basic types | |||||
//! @{ | |||||
//! bool_ type: integral constant wrapper for bool | |||||
template<bool v> | |||||
using bool_ = integral_<bool, v>; | |||||
using true_ = bool_<true>; //!< The type used as a compile-time boolean with true value. | |||||
using false_ = bool_<false>; //!< The type used as a compile-time boolean with false value. | |||||
//! int8_ type: integral constant wrapper for \c int8_t | |||||
template<int8_t v> | |||||
using int8_ = integral_<int8_t, v>; | |||||
//! uint8_ type: integral constant wrapper for \c uint8_t | |||||
template<uint8_t v> | |||||
using uint8_ = integral_<uint8_t, v>; | |||||
//! int16_ type: integral constant wrapper for \c int16_t | |||||
template<int16_t v> | |||||
using int16_ = integral_<int16_t, v>; | |||||
//! uint16_ type: integral constant wrapper for \c uint16_t | |||||
template<uint16_t v> | |||||
using uint16_ = integral_<uint16_t, v>; | |||||
//! int32_ type: integral constant wrapper for \c int32_t | |||||
template<int32_t v> | |||||
using int32_ = integral_<int32_t, v>; | |||||
//! uint32_ type: integral constant wrapper for \c uint32_t | |||||
template<uint32_t v> | |||||
using uint32_ = integral_<uint32_t, v>; | |||||
//! char_ type: integral constant wrapper for \c char | |||||
template<char v> | |||||
using char_ = integral_<char, v>; | |||||
//! int_ type: integral constant wrapper for \c int | |||||
template<int v> | |||||
using int_ = integral_<int, v>; | |||||
//! long_ type: integral constant wrapper for \c long | |||||
template<long v> | |||||
using long_ = integral_<long, v>; | |||||
//! index_ type: integral constant wrapper for \c index_t a.k.a std::size_t | |||||
template<index_t v> | |||||
using index_ = integral_<index_t, v>; | |||||
//! size_ type: integral constant wrapper for \c size_t a.k.a std::size_t | |||||
template<size_t v> | |||||
using size_ = integral_<size_t, v>; | |||||
//! The last position we can express for indexing | |||||
using Npos = size_<index_t(-1)>; | |||||
//! @} | |||||
//! \name unevaluated expressions | |||||
//! @{ | |||||
//! Computes the size of the type \p Tp. | |||||
//! Complexity \f$ O(1) \f$. | |||||
template <typename Tp> | |||||
using sizeof_ = size_<sizeof(Tp)>; | |||||
//! Computes the alignment required for any instance of the type \p Tp. | |||||
//! Complexity \f$ O(1) \f$. | |||||
template <typename Tp> | |||||
using alignof_ = size_<alignof(Tp)>; | |||||
//! @} | |||||
//! \name integer sequence | |||||
//! @{ | |||||
template< class Tp, Tp... Ints > | |||||
using integer_sequence = std::integer_sequence<Tp, Ints...>; | |||||
template<typename Tp, Tp Num> | |||||
using make_integer_sequence = std::make_integer_sequence<Tp, Num>; | |||||
//! Alias template index_sequence | |||||
template<index_t... Idx> | |||||
using index_sequence = integer_sequence<index_t, Idx...>; | |||||
//! Alias template make_index_sequence | |||||
template<index_t Num> | |||||
using make_index_sequence = make_integer_sequence <index_t, Num>; | |||||
//! Alias template index_sequence_for | |||||
template<typename... Types> | |||||
using index_sequence_for = make_index_sequence<sizeof...(Types)>; | |||||
//! @} | |||||
}} | |||||
//!@} | |||||
/*! | |||||
* \ingroup basic | |||||
* \defgroup selection Selection | |||||
* Type selection support header | |||||
*/ | |||||
//! @{ | |||||
namespace utl { | |||||
namespace meta{ | |||||
//! \name if implementation | |||||
//! @{ | |||||
namespace details { | |||||
template <bool If, typename...> | |||||
struct if_c_ { | |||||
using type = nil_; //< avoid ill formed result | |||||
}; | |||||
template<typename Then> | |||||
struct if_c_<true, Then> { | |||||
using type = Then; | |||||
}; | |||||
template<typename Then, typename Else> | |||||
struct if_c_<true, Then, Else> { | |||||
using type = Then; | |||||
}; | |||||
template<typename Then, typename Else> | |||||
struct if_c_<false, Then, Else> { | |||||
using type = Else; | |||||
}; | |||||
} | |||||
//! Select one type or another depending on a compile-time Boolean. | |||||
template <bool B, typename... Args> | |||||
using if_c = eval<details::if_c_<B, Args...>>; | |||||
//! Select one type or another depending on a compile-time Boolean type | |||||
template <typename If, typename... Args> | |||||
using if_ = if_c<If::type::value, Args...>; | |||||
//! @} | |||||
/*! | |||||
* \name Named type selectors | |||||
*/ | |||||
//! @{ | |||||
//! Select the first type of a type sequence | |||||
template <typename T1, typename ...> using first_of = T1; | |||||
//! Select the second type of a type sequence | |||||
template <typename T1, typename T2, typename ...> using second_of = T2; | |||||
//! @} | |||||
}} | |||||
//! @} | |||||
/*! | |||||
* \ingroup basic | |||||
* \defgroup logic_operations Logic Operations | |||||
* logic operators and type relations support | |||||
*/ | |||||
//! @{ | |||||
namespace utl { | |||||
namespace meta{ | |||||
/*! | |||||
* \name Logical relation for types | |||||
*/ | |||||
//! @{ | |||||
//! Negate the *bool* constant parameter and return bool_ | |||||
template <bool B> | |||||
using not_c = bool_<!B>; | |||||
//! negate the bool_ parameter and return bool_ | |||||
template<typename Tp> | |||||
using not_ = not_c<Tp::type::value>; | |||||
//! \name OR implementation | |||||
//! @{ | |||||
namespace details { | |||||
template<typename...> struct _or_; | |||||
template<> | |||||
struct _or_<> : false_ { }; | |||||
template<typename T1> | |||||
struct _or_<T1> : T1 { }; | |||||
template<typename T1, typename T2> | |||||
struct _or_ <T1, T2> | |||||
: if_<T1, T1, T2> { }; | |||||
template<typename T1, typename T2, typename T3, typename... Tn> | |||||
struct _or_<T1, T2, T3, Tn...> | |||||
: if_<T1, T1, _or_<T2, T3, Tn...>> { }; | |||||
} | |||||
//! Operator or for bool_ types | |||||
//! \tparam Ts Variadic args of type bool_ | |||||
//! \return Logical or as bool_ | |||||
template <typename... Ts> | |||||
using or_ = eval<details::_or_<Ts...>>; | |||||
//! @} | |||||
//! \name AND implementation | |||||
//! @{ | |||||
namespace details { | |||||
template<typename...> struct _and_; | |||||
template<> | |||||
struct _and_<> | |||||
: true_ { }; | |||||
template<typename T1> | |||||
struct _and_ <T1> | |||||
: T1 { }; | |||||
template<typename T1, typename T2> | |||||
struct _and_<T1, T2> | |||||
: if_<T1, T2, T1> { }; | |||||
template<typename T1, typename T2, typename T3, typename... Tn> | |||||
struct _and_<T1, T2, T3, Tn...> | |||||
: if_<T1, _and_<T2, T3, Tn...>, T1> { }; | |||||
} | |||||
//! Operator and for bool_ types | |||||
//! \tparam Ts Variadic args of type bool_ | |||||
//! \return Logical and as bool_ | |||||
template <typename... Ts> | |||||
using and_ = eval<details::_and_<Ts...>>; | |||||
//! @} | |||||
//! \name same | |||||
//! @{ | |||||
template<typename T1, typename T2> | |||||
struct same_ : false_ { }; | |||||
template<typename Tp> | |||||
struct same_ <Tp, Tp> : true_ { }; | |||||
template<typename T1, typename T2> | |||||
using not_same_ = not_<eval<same_<T1, T2>>>; | |||||
//! @} | |||||
//! @} | |||||
}} | |||||
//! @} | |||||
/*! | |||||
* \ingroup basic | |||||
* \defgroup integral_operators integral operators | |||||
* Type arithmetic and operations | |||||
*/ | |||||
//! @{ | |||||
namespace utl { | |||||
namespace meta { | |||||
/*! | |||||
* \name Math operations | |||||
*/ | |||||
//! @{ | |||||
//! Negation | |||||
template <typename Tp> | |||||
using negate = integral_<decltype(-Tp()), -Tp()>; | |||||
//! Addition | |||||
template <typename Tp1, typename Tp2> | |||||
using add = integral_< | |||||
decltype(Tp1() + Tp2()), | |||||
Tp1() + Tp2() | |||||
>; | |||||
//! Multiplication | |||||
template <typename Tp1, typename Tp2> | |||||
using mult = integral_< | |||||
decltype(Tp2() * Tp2()), | |||||
Tp1() * Tp2() | |||||
>; | |||||
//! Division | |||||
template <typename Tp1, typename Tp2> | |||||
using divide = integral_< | |||||
decltype(Tp2() / Tp2()), | |||||
Tp1() / Tp2() | |||||
>; | |||||
//! Modulo | |||||
template <typename Tp1, typename Tp2> | |||||
using modulo = integral_< | |||||
decltype(Tp1() % Tp2()), | |||||
Tp1() % Tp2() | |||||
>; | |||||
//! Substruction | |||||
template <typename Tp1, typename Tp2> | |||||
using sub = add<Tp1, negate<Tp2>>; | |||||
//! Increase | |||||
template <typename Tp> | |||||
using inc = add<Tp, int_<1>>; | |||||
//! decrease | |||||
template <typename Tp> | |||||
using dec = add<Tp, int_<-1>>; | |||||
//! @} | |||||
/*! | |||||
* \name Comparison operations | |||||
*/ | |||||
//! @{ | |||||
//! \return a true-valued Integral Constant if Tp1 and Tp2 are equal. | |||||
template <typename Tp1, typename Tp2> using comp_eq = bool_<Tp1() == Tp2()>; | |||||
//! \return a true-valued Integral Constant if Tp1 is less than Tp2. | |||||
template <typename Tp1, typename Tp2> using comp_lt = bool_<(Tp1() < Tp2())>; | |||||
//! Not equal | |||||
template <typename Tp1, typename Tp2> using comp_ne = not_<comp_eq<Tp1, Tp2>>; | |||||
//! Greater than | |||||
template <typename Tp1, typename Tp2> using comp_gt = comp_lt <Tp2, Tp1>; | |||||
//! Less or equal | |||||
template <typename Tp1, typename Tp2> using comp_le = not_<comp_lt<Tp2, Tp1>>; | |||||
//! Greater or equal | |||||
template <typename Tp1, typename Tp2> using comp_ge = not_<comp_lt<Tp1, Tp2>>; | |||||
//! @} | |||||
/*! | |||||
* \name Bitwise operations | |||||
*/ | |||||
//! @{ | |||||
//! \return bitwise not (~) operation of its argument. | |||||
template <typename T> using bitnot_ = integral_<typename T::value_type, (typename T::value_type)(~T())>; | |||||
//! \return bitwise and (&) operation of its arguments | |||||
template <typename Tp1, typename Tp2> | |||||
using bitand_ = integral_<decltype(Tp1() & Tp2()), Tp1() & Tp2()>; | |||||
//! \return bitwise or (|) operation of its arguments. | |||||
template <typename Tp1, typename Tp2> | |||||
using bitor_ = integral_<decltype(Tp1() | Tp2()), Tp1() | Tp2()>; | |||||
//! \return bitwise xor (^) operation of its arguments. | |||||
template <typename Tp1, typename Tp2> | |||||
using bitxor_ = integral_<decltype(Tp1() ^ Tp2()), Tp1() ^ Tp2()>; | |||||
//! \return the result of bitwise shift left (<<) operation on Tp. | |||||
template <typename Tp, typename shift> | |||||
using shift_left = integral_<typename Tp::value_type, (typename Tp::value_type)(Tp() << shift())>; | |||||
//! \return the result of bitwise shift right (>>) operation on Tp. | |||||
template <typename Tp, typename shift> | |||||
using shift_right = integral_<typename Tp::value_type, (typename Tp::value_type)(Tp() >> shift())>; | |||||
//! @} | |||||
}} | |||||
//! @} | |||||
//! @} | |||||
#endif /* __utl_meta_basic_h__ */ |
@@ -1,34 +1,17 @@ | |||||
/*! | /*! | ||||
* \file detection.h | * \file detection.h | ||||
* \brief Detection idiom based on WG21's N4502 [\ref 1] from Walter E. Brown | |||||
* | |||||
* Copyright (C) 2018-2019 Christos Choutouridis | |||||
* | |||||
* This program is free software: you can redistribute it and/or modify | |||||
* it under the terms of the GNU Lesser General Public License as | |||||
* published by the Free Software Foundation, either version 3 | |||||
* of the License, or (at your option) any later version. | |||||
* | |||||
* This program is distributed in the hope that it will be useful, | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
* GNU Lesser General Public License for more details. | |||||
* | |||||
* You should have received a copy of the GNU Lesser General Public License | |||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||||
* | |||||
* \anchor [1]: www.open-std.org/jtc1/sc22/wg21/docs/papers/2015/n4502.pdf | |||||
* \brief Detection idiom based on WG21's N4502 from Walter E. Brown | |||||
*/ | */ | ||||
#ifndef __utl_meta_detection_h__ | #ifndef __utl_meta_detection_h__ | ||||
#define __utl_meta_detection_h__ | #define __utl_meta_detection_h__ | ||||
#include <utl/core/impl.h> | #include <utl/core/impl.h> | ||||
#include <utl/meta/operations.h> | |||||
#include <utl/meta/basic.h> | |||||
#include <type_traits> | #include <type_traits> | ||||
/*! | /*! | ||||
* \ingroup meta | * \ingroup meta | ||||
* \defgroup detection | |||||
* \defgroup detection Detection | |||||
* Detection idiom support header. | * Detection idiom support header. | ||||
*/ | */ | ||||
//! @{ | //! @{ | ||||
@@ -37,7 +20,7 @@ namespace utl { | |||||
namespace meta { | namespace meta { | ||||
/*! | /*! | ||||
* void_t meta-function that maps a sequence of any types to the type void | |||||
* \name void_t implementation | |||||
*/ | */ | ||||
//! @{ | //! @{ | ||||
#if defined(UTL_WORKAROUND_CWG_1558) | #if defined(UTL_WORKAROUND_CWG_1558) | ||||
@@ -49,16 +32,18 @@ namespace meta { | |||||
template<typename... _Ts> | template<typename... _Ts> | ||||
using void_t = eval<void_<_Ts...>>; | using void_t = eval<void_<_Ts...>>; | ||||
#else | #else | ||||
//! void_ type alias | |||||
//! void_ meta-function that maps a sequence of any types to the type void | |||||
template <typename...> using void_ = void; | template <typename...> using void_ = void; | ||||
//! void_t type alias | |||||
//! void_t meta-function that maps a sequence of any types to the type void | |||||
template <typename...> using void_t = void; | template <typename...> using void_t = void; | ||||
#endif | #endif | ||||
//! @} | //! @} | ||||
/*! | /*! | ||||
* Not a type to use in detected idiom. This type can | |||||
* not be constructed, destructed or copied | |||||
* \brief | |||||
* Not a type to use in detected idiom. | |||||
* | |||||
* This type can not be constructed, destructed or copied. | |||||
*/ | */ | ||||
struct nat_ { | struct nat_ { | ||||
nat_() = delete; | nat_() = delete; | ||||
@@ -67,9 +52,9 @@ namespace meta { | |||||
void operator = (nat_ const&) = delete; | void operator = (nat_ const&) = delete; | ||||
}; | }; | ||||
//! Detector for detection idiom | |||||
//! \name Detector for detection idiom | |||||
//! @{ | //! @{ | ||||
namespace detail { | |||||
namespace details { | |||||
template <typename Default, | template <typename Default, | ||||
typename AlwaysVoid, | typename AlwaysVoid, | ||||
template<typename...> class Op, typename... Args> | template<typename...> class Op, typename... Args> | ||||
@@ -89,24 +74,23 @@ namespace meta { | |||||
template <typename Default, | template <typename Default, | ||||
template<typename...> class Op, typename... Args> | template<typename...> class Op, typename... Args> | ||||
using detected_or = detector<Default, void, Op, Args...>; | using detected_or = detector<Default, void, Op, Args...>; | ||||
} // namespace detail | |||||
} // namespace details | |||||
//! @} | //! @} | ||||
/*! | /*! | ||||
* detection interface | |||||
* \name detection interface | |||||
*/ | */ | ||||
//! @{ | //! @{ | ||||
/*! | /*! | ||||
* Checks if Op<Args...> is a valid expression without evaluating it. | * Checks if Op<Args...> is a valid expression without evaluating it. | ||||
* | * | ||||
* \tparam Op a meta-callback function to pass Args... | |||||
* \tparam Args... types to pass to Op for checking | |||||
* \tparam Op a meta-callback function to pass Args... | |||||
* \tparam Args... types to pass to Op for checking | |||||
* \return status of the operation [bool_] | * \return status of the operation [bool_] | ||||
* \arg true_ if Op<Args...> is valid expression | * \arg true_ if Op<Args...> is valid expression | ||||
* \arg false_ if Op<Args...> is not valid | * \arg false_ if Op<Args...> is not valid | ||||
* | * | ||||
* \example | |||||
* \code | * \code | ||||
* // archetypal alias for a copy assignment operation | * // archetypal alias for a copy assignment operation | ||||
* template< class T > using copy_assign_t = decltype( declval<T&>() = declval<T const &>() ); | * template< class T > using copy_assign_t = decltype( declval<T&>() = declval<T const &>() ); | ||||
@@ -115,7 +99,7 @@ namespace meta { | |||||
* \endcode | * \endcode | ||||
*/ | */ | ||||
template <template<typename...> class Op, typename... Args> | template <template<typename...> class Op, typename... Args> | ||||
using is_detected = typename detail::detector<nat_, void, Op, Args...>::detected; | |||||
using is_detected = typename details::detector<nat_, void, Op, Args...>::detected; | |||||
//! Detection predicate | //! Detection predicate | ||||
template< template<typename...> class Op, typename... Args> | template< template<typename...> class Op, typename... Args> | ||||
@@ -124,12 +108,12 @@ namespace meta { | |||||
/*! | /*! | ||||
* Detection tool that evaluates to Op<Args...> if it's valid and to nat_ if not | * Detection tool that evaluates to Op<Args...> if it's valid and to nat_ if not | ||||
* | * | ||||
* \param Op metafunction detector | |||||
* \param Args... The arguments to pass to \p Op and check if is well formed | |||||
* \tparam Op metafunction detector | |||||
* \tparam Args... The arguments to pass to \p Op and check if is well formed | |||||
* \return The result type | * \return The result type | ||||
* \arg Op<Args...> if is well formed | * \arg Op<Args...> if is well formed | ||||
* \arg nat_ if Op<Args...> is ill formed | * \arg nat_ if Op<Args...> is ill formed | ||||
* \example | |||||
* | |||||
* \code | * \code | ||||
* template <typename T> using try_type = typename T::type; // detector | * template <typename T> using try_type = typename T::type; // detector | ||||
* template <typename T> using try_ppT = decltype (++(std::declval<T>())); // detector | * template <typename T> using try_ppT = decltype (++(std::declval<T>())); // detector | ||||
@@ -142,19 +126,19 @@ namespace meta { | |||||
*/ | */ | ||||
template <template<typename...> class Op, typename... Args> | template <template<typename...> class Op, typename... Args> | ||||
using detected_t = eval < | using detected_t = eval < | ||||
detail::detector<nat_, void, Op, Args...> | |||||
details::detector<nat_, void, Op, Args...> | |||||
>; | >; | ||||
/*! | /*! | ||||
* Detection tool that evaluates to Op<Args...> if it's valid and to \p Default if not | * Detection tool that evaluates to Op<Args...> if it's valid and to \p Default if not | ||||
* | * | ||||
* \param Default The resulting type if detection fail | |||||
* \param Op metafunction detector | |||||
* \param Args... The arguments to pass to \p Op and check if is well formed | |||||
* \tparam Default The resulting type if detection fail | |||||
* \tparam Op metafunction detector | |||||
* \tparam Args... The arguments to pass to \p Op and check if is well formed | |||||
* \return The result type | * \return The result type | ||||
* \arg Op<Args...> if is well formed | * \arg Op<Args...> if is well formed | ||||
* \arg Default if Op<Args...> is ill formed | * \arg Default if Op<Args...> is ill formed | ||||
* \example | |||||
* | |||||
* \code | * \code | ||||
* template <typename T> using try_type = typename T::type; // detector | * template <typename T> using try_type = typename T::type; // detector | ||||
* template <typename T> using try_ppT = decltype (++(std::declval<T>())); // detector | * template <typename T> using try_ppT = decltype (++(std::declval<T>())); // detector | ||||
@@ -168,20 +152,20 @@ namespace meta { | |||||
template <typename Default, | template <typename Default, | ||||
template<typename...> class Op, typename... Args> | template<typename...> class Op, typename... Args> | ||||
using detected_or_t = eval < | using detected_or_t = eval < | ||||
detail::detected_or<Default, Op, Args...> | |||||
details::detected_or<Default, Op, Args...> | |||||
>; | >; | ||||
/*! | /*! | ||||
* Detection tool that evaluates to true_ if evaluation of Op<Args...> | * Detection tool that evaluates to true_ if evaluation of Op<Args...> | ||||
* is \p Expected and to false_ if not | * is \p Expected and to false_ if not | ||||
* | * | ||||
* \param Expected The expected resulting type if detection succeed | |||||
* \param Op metafunction detector | |||||
* \param Args... The arguments to pass to \p Op and check if is well formed | |||||
* \tparam Expected The expected resulting type if detection succeed | |||||
* \tparam Op metafunction detector | |||||
* \tparam Args... The arguments to pass to \p Op and check if is well formed | |||||
* \return The result type | * \return The result type | ||||
* \arg true_ if Op<Args...> is well formed and evaluate to Expected | * \arg true_ if Op<Args...> is well formed and evaluate to Expected | ||||
* \arg false_ Any other case | * \arg false_ Any other case | ||||
* \example | |||||
* | |||||
* \code | * \code | ||||
* template <typename T> using try_type = typename T::type; // detector | * template <typename T> using try_type = typename T::type; // detector | ||||
* template <typename T> using try_ppT = decltype (++(std::declval<T>())); // detector | * template <typename T> using try_ppT = decltype (++(std::declval<T>())); // detector | ||||
@@ -207,13 +191,13 @@ namespace meta { | |||||
* Detection tool that evaluates to true_ if evaluation of Op<Args...> is convertible | * Detection tool that evaluates to true_ if evaluation of Op<Args...> is convertible | ||||
* to \p To and to false_ if not | * to \p To and to false_ if not | ||||
* | * | ||||
* \param To The to convert to if detection succeed | |||||
* \param Op metafunction detector | |||||
* \param Args... The arguments to pass to \p Op and check if is well formed | |||||
* \tparam To The to convert to if detection succeed | |||||
* \tparam Op metafunction detector | |||||
* \tparam Args... The arguments to pass to \p Op and check if is well formed | |||||
* \return The result type | * \return The result type | ||||
* \arg true_ if Op<Args...> is well formed and convertible to To | * \arg true_ if Op<Args...> is well formed and convertible to To | ||||
* \arg false_ Any other case | * \arg false_ Any other case | ||||
* \example | |||||
* | |||||
* \code | * \code | ||||
* template <typename T> using try_type = typename T::type; // detector | * template <typename T> using try_type = typename T::type; // detector | ||||
* template <typename T> using try_ppT = decltype (++(std::declval<T>())); // detector | * template <typename T> using try_ppT = decltype (++(std::declval<T>())); // detector | ||||
@@ -1,151 +0,0 @@ | |||||
/*! | |||||
* \file integralconstant.h | |||||
* \brief Template meta-programming integral constant | |||||
* | |||||
* Copyright (C) 2018-2019 Christos Choutouridis | |||||
* | |||||
* This program is free software: you can redistribute it and/or modify | |||||
* it under the terms of the GNU Lesser General Public License as | |||||
* published by the Free Software Foundation, either version 3 | |||||
* of the License, or (at your option) any later version. | |||||
* | |||||
* This program is distributed in the hope that it will be useful, | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
* GNU Lesser General Public License for more details. | |||||
* | |||||
* You should have received a copy of the GNU Lesser General Public License | |||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||||
*/ | |||||
#ifndef __utl_meta_integralconstant_h__ | |||||
#define __utl_meta_integralconstant_h__ | |||||
#include <utl/core/impl.h> | |||||
#include <type_traits> | |||||
#include <utility> | |||||
/*! | |||||
* \ingroup meta | |||||
* \defgroup integral | |||||
* integral constant support header | |||||
*/ | |||||
//! @{ | |||||
namespace utl { | |||||
namespace meta { | |||||
/*! | |||||
* Empty type | |||||
* utl::meta's nil type is not pure nil. It's a recursive "de-referencable nil. | |||||
* Each time someone applies ::type to it, he gets back nil_. This way we can prevent | |||||
* a lot of compilation errors in a wrong meta:: handling. | |||||
*/ | |||||
struct nil_ { | |||||
using type = nil_; | |||||
}; | |||||
//! Type alias for \p Tp::type. Used to evaluate/extract return type of metafunctions | |||||
template <typename Tp> | |||||
using eval = typename Tp::type; | |||||
//! integral_ | |||||
//! Integral Constant is a holder class for a compile-time value of an integral type. | |||||
//! Every Integral Constant is also a null-ary Metafunction, returning itself. | |||||
//! An integral constant object is implicitly convertible to the corresponding | |||||
//! run-time value of the wrapped integral type | |||||
//! @{ | |||||
template <typename Tp, Tp v> | |||||
using integral_ = std::integral_constant<Tp, v>; | |||||
//! @} | |||||
//! Wrappers for basic types | |||||
//! @{ | |||||
//! bool_ type: integral constant wrapper for bool | |||||
template<bool v> | |||||
using bool_ = integral_<bool, v>; | |||||
using true_ = bool_<true>; //!< The type used as a compile-time boolean with true value. | |||||
using false_ = bool_<false>; //!< The type used as a compile-time boolean with false value. | |||||
//! int8_ type: integral constant wrapper for \c int8_t | |||||
template<int8_t v> | |||||
using int8_ = integral_<int8_t, v>; | |||||
//! uint8_ type: integral constant wrapper for \c uint8_t | |||||
template<uint8_t v> | |||||
using uint8_ = integral_<uint8_t, v>; | |||||
//! int16_ type: integral constant wrapper for \c int16_t | |||||
template<int16_t v> | |||||
using int16_ = integral_<int16_t, v>; | |||||
//! uint16_ type: integral constant wrapper for \c uint16_t | |||||
template<uint16_t v> | |||||
using uint16_ = integral_<uint16_t, v>; | |||||
//! int32_ type: integral constant wrapper for \c int32_t | |||||
template<int32_t v> | |||||
using int32_ = integral_<int32_t, v>; | |||||
//! uint32_ type: integral constant wrapper for \c uint32_t | |||||
template<uint32_t v> | |||||
using uint32_ = integral_<uint32_t, v>; | |||||
//! char_ type: integral constant wrapper for \c char | |||||
template<char v> | |||||
using char_ = integral_<char, v>; | |||||
//! int_ type: integral constant wrapper for \c int | |||||
template<int v> | |||||
using int_ = integral_<int, v>; | |||||
//! long_ type: integral constant wrapper for \c long | |||||
template<long v> | |||||
using long_ = integral_<long, v>; | |||||
//! index_ type: integral constant wrapper for \c index_t a.k.a std::size_t | |||||
template<index_t v> | |||||
using index_ = integral_<index_t, v>; | |||||
//! size_ type: integral constant wrapper for \c size_t a.k.a std::size_t | |||||
template<size_t v> | |||||
using size_ = integral_<size_t, v>; | |||||
//! Computes the size of the type \p Tp. | |||||
//! Complexity \f$ O(1) \f$. | |||||
template <typename Tp> | |||||
using sizeof_ = size_<sizeof(Tp)>; | |||||
//! Computes the alignment required for any instance of the type \p Tp. | |||||
//! Complexity \f$ O(1) \f$. | |||||
template <typename Tp> | |||||
using alignof_ = size_<alignof(Tp)>; | |||||
//! @} | |||||
//! The last position we can express for indexing | |||||
using Npos = size_<index_t(-1)>; | |||||
//! integer sequence | |||||
//! @{ | |||||
template< class Tp, Tp... Ints > | |||||
using integer_sequence = std::integer_sequence<Tp, Ints...>; | |||||
template<typename Tp, Tp Num> | |||||
using make_integer_sequence = std::make_integer_sequence<Tp, Num>; | |||||
//! Alias template index_sequence | |||||
template<index_t... Idx> | |||||
using index_sequence = integer_sequence<index_t, Idx...>; | |||||
//! Alias template make_index_sequence | |||||
template<index_t Num> | |||||
using make_index_sequence = make_integer_sequence <index_t, Num>; | |||||
//! Alias template index_sequence_for | |||||
template<typename... Types> | |||||
using index_sequence_for = make_index_sequence<sizeof...(Types)>; | |||||
//! @} | |||||
}} | |||||
//!@} | |||||
#endif /* __utl_meta_integralconstant_h__ */ |
@@ -1,75 +1,64 @@ | |||||
/*! | /*! | ||||
* \file invoke.h | |||||
* \file utl/meta/invoke.h | |||||
* \brief Template meta-programming utilities for callables | * \brief Template meta-programming utilities for callables | ||||
* | |||||
* Copyright (C) 2018 Christos Choutouridis | |||||
* | |||||
* This program is free software: you can redistribute it and/or modify | |||||
* it under the terms of the GNU Lesser General Public License as | |||||
* published by the Free Software Foundation, either version 3 | |||||
* of the License, or (at your option) any later version. | |||||
* | |||||
* This program is distributed in the hope that it will be useful, | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
* GNU Lesser General Public License for more detail. | |||||
* | |||||
* You should have received a copy of the GNU Lesser General Public License | |||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||||
*/ | */ | ||||
#ifndef __utl_meta_invoke_h__ | #ifndef __utl_meta_invoke_h__ | ||||
#define __utl_meta_invoke_h__ | #define __utl_meta_invoke_h__ | ||||
#include <utl/core/impl.h> | #include <utl/core/impl.h> | ||||
#include <utl/meta/integral.h> | |||||
#include <utl/meta/basic.h> | |||||
#include <utl/meta/detection.h> | #include <utl/meta/detection.h> | ||||
#include <utl/meta/operations.h> | |||||
/*! | /*! | ||||
* \ingroup meta | * \ingroup meta | ||||
* \defgroup invoke | |||||
* \defgroup meta_invoke Invoke | |||||
* A meta-programming invoke() analogous. | |||||
* | |||||
* This module provides <b>higher order</b> tools to meta. utl::meta's metafunctions inputs are types. | |||||
* The metafunctions though are templates in the form of `template <typename...> class`. | |||||
* So we can not pass metafunctions to other metafunctions. The utl::meta provides tools to wrap metafunctions | |||||
* in a type. This way we create the concepts of: | |||||
* | |||||
* - <b>\c invocable</b> which is a type containing a metafunction inside. | |||||
* - <b>\c evaluation</b> which is the way of unwrapping the metafunction inside the invocable type. | |||||
* | |||||
* In order to accomplish that, by convention, a \c meta::invocable shall contain a nested | |||||
* template type named \c apply which is bind to actual invocable meta-function. Then we can: | |||||
* | * | ||||
* - Use \c wrap<> or even better \c quote<> in order to wrap a metafunction to a type (metafunction class) | |||||
* - Pass these wrapped types to other metafunctions | |||||
* - \c invoke<> the inner \c apply from a wrapped metafunction class. | |||||
*/ | */ | ||||
//! @{ | //! @{ | ||||
namespace utl { | namespace utl { | ||||
namespace meta{ | namespace meta{ | ||||
/*! | /*! | ||||
* \name meta::invoke | |||||
* | |||||
* A meta-programming invoke() analogous. A \c meta::invocable shall contain a nested | |||||
* template type named \b apply which is bind to actual invocable meta-function. | |||||
* | |||||
* - We can use \c wrap<> or even better \c quote<> in order to wrap a metafunction to a type (metafunction class) | |||||
* - We can pass these wrapped types to other metafunctions | |||||
* - We can \c invoke<> the inner \c apply from a wrapped metafunction class. | |||||
* \name identity implementation | |||||
*/ | */ | ||||
//! @{ | //! @{ | ||||
/*! | |||||
* identity, identity_t. | |||||
*/ | |||||
//! @{ | |||||
template <typename _Tp> | |||||
//! Identity is a metafunction always return the input type | |||||
template <typename Tp> | |||||
struct identity { | struct identity { | ||||
#if defined (UTL_WORKAROUND_CWG_1558) | #if defined (UTL_WORKAROUND_CWG_1558) | ||||
// redirect unused Ts... via void_t | // redirect unused Ts... via void_t | ||||
template <typename... Ts> | template <typename... Ts> | ||||
using apply = first_of<_Tp, void_t<Ts...>>; //!< identity is invokable, must also have apply | |||||
using apply = first_of<Tp, void_t<Ts...>>; //!< identity is invokable, must also have apply | |||||
#else | #else | ||||
template <typename...> | template <typename...> | ||||
using apply = _Tp; //!< identity is invokable, must also have apply | |||||
using apply = Tp; //!< identity is invokable, must also have apply | |||||
#endif | #endif | ||||
using type = _Tp; //!< identity | |||||
using type = Tp; //!< identity | |||||
}; | }; | ||||
//! identity type alias | //! identity type alias | ||||
template <typename _Tp> | |||||
using identity_t = eval<identity<_Tp>>; | |||||
template <typename Tp> | |||||
using identity_t = eval<identity<Tp>>; | |||||
//! @} | //! @} | ||||
/*! | /*! | ||||
* invoke, invoke_t | |||||
* \name invoke, invoke_t | |||||
*/ | */ | ||||
//! @{ | //! @{ | ||||
/*! | /*! | ||||
@@ -88,13 +77,19 @@ namespace meta{ | |||||
using invoke_t = eval< invoke <Fn, Args...>>; | using invoke_t = eval< invoke <Fn, Args...>>; | ||||
//! @} | //! @} | ||||
//! wrap | |||||
//! \name wrap | |||||
//! @{ | //! @{ | ||||
/*! | /*! | ||||
* \brief | |||||
* Wraps an n-ary Metafunction \c F to a Metafunction Class | |||||
* | |||||
* wrap is a higher-order primitive that wraps an n-ary Metafunction | * wrap is a higher-order primitive that wraps an n-ary Metafunction | ||||
* to create a corresponding Metafunction Class (Invocable). This way | * to create a corresponding Metafunction Class (Invocable). This way | ||||
* we can pass Metafunctions as types to other metafunctions and let | * we can pass Metafunctions as types to other metafunctions and let | ||||
* them \c invoke the inner templated apply | |||||
* them \c invoke the inner templated apply. | |||||
* | |||||
* \tparam F The metafunction to wrap | |||||
*/ | */ | ||||
template <template <typename...> class F> | template <template <typename...> class F> | ||||
struct wrap { | struct wrap { | ||||
@@ -102,7 +97,19 @@ namespace meta{ | |||||
using apply = F<Args...>; | using apply = F<Args...>; | ||||
}; | }; | ||||
//! Wrap a template \p F taking literal constants of type \p T into an Invokable | |||||
/*! | |||||
* \brief | |||||
* Wraps an n-ary Metafunction \c F taking literal constants of type \c T | |||||
* to a Metafunction Class | |||||
* | |||||
* wrap_i is a higher-order primitive that wraps an n-ary Metafunction | |||||
* to create a corresponding Metafunction Class (Invocable). | |||||
* This way we can pass Metafunctions as types to other metafunctions and let | |||||
* them \c invoke the inner templated apply. | |||||
* | |||||
* \tparam T Type of integral constants | |||||
* \tparam F The metafunction to wrap | |||||
*/ | |||||
template <typename T, template <T...> class F> | template <typename T, template <T...> class F> | ||||
struct wrap_i { | struct wrap_i { | ||||
// requires meta::Integral | // requires meta::Integral | ||||
@@ -111,9 +118,9 @@ namespace meta{ | |||||
}; | }; | ||||
//! @} | //! @} | ||||
//! Is applicable trait | |||||
//! \name Is applicable trait | |||||
//! @{ | //! @{ | ||||
namespace detail { | |||||
namespace details { | |||||
template<template<typename...> class F, typename... T> | template<template<typename...> class F, typename... T> | ||||
struct is_applicable_ { | struct is_applicable_ { | ||||
@@ -156,29 +163,51 @@ namespace meta{ | |||||
}; | }; | ||||
} | } | ||||
//! check if we can instantiate \p F with parameters \p T | |||||
template<template<typename...> class F, typename... T> | |||||
/*! | |||||
* \brief | |||||
* Check if we can instantiate metafunction \c F with parameters \p Ts | |||||
* | |||||
* \tparam F The metafunction | |||||
* \tparam Ts The parameters to \c F | |||||
*/ | |||||
template<template<typename...> class F, typename... Ts> | |||||
using is_applicable_t = eval< | using is_applicable_t = eval< | ||||
detail::is_applicable_<F, T...> | |||||
details::is_applicable_<F, Ts...> | |||||
>; | >; | ||||
//! check if we can invoke \p Q with parameters \p T | |||||
template<typename Q, typename... T> | |||||
/*! | |||||
* \brief | |||||
* Check if we can invoke the quoted metafunction \c Q with parameters \p Ts | |||||
* | |||||
* \tparam Q The quoted metafunction | |||||
* \tparam Ts The parameters to \c Q | |||||
* | |||||
* \sa utl::meta::quote | |||||
*/ | |||||
template<typename Q, typename... Ts> | |||||
using is_applicable_qt = eval < | using is_applicable_qt = eval < | ||||
detail::is_applicable_q_ <Q, T...> | |||||
details::is_applicable_q_ <Q, Ts...> | |||||
>; | >; | ||||
//! check if we can instantiate \p F with parameters \p Is of type \p T | |||||
/*! | |||||
* \brief | |||||
* Check if we can instantiate metafunction \c F with parameters \p Is of type \c T | |||||
* | |||||
* \tparam T The type of \c Is | |||||
* \tparam F The metafunction | |||||
* \tparam Is The parameters to \c F | |||||
*/ | |||||
template <typename T, template<T...> class F, T... Is> | template <typename T, template<T...> class F, T... Is> | ||||
using is_applicable_it = eval< | using is_applicable_it = eval< | ||||
detail::is_applicable_i_<T, F, Is...> | |||||
details::is_applicable_i_<T, F, Is...> | |||||
>; | >; | ||||
//! @} | //! @} | ||||
//! defer | |||||
//! \name defer | |||||
//! @{ | //! @{ | ||||
namespace detail { | |||||
//! @{ | |||||
namespace details { | |||||
template<template<typename...> class F, typename... Ts> | template<template<typename...> class F, typename... Ts> | ||||
struct defer_ { | struct defer_ { | ||||
using type = F<Ts...>; | using type = F<Ts...>; | ||||
@@ -194,41 +223,64 @@ namespace meta{ | |||||
//! template<template<typename...> class F, typename... Ts> | //! template<template<typename...> class F, typename... Ts> | ||||
//! using defer_ = F<Ts...>; | //! using defer_ = F<Ts...>; | ||||
//! | //! | ||||
//! The use of struct here is due to Core issue 1430 [\ref link1 1] and is used | |||||
//! as suggested by Roy Crihfield in [\ref link2 2]. | |||||
//! The use of struct here is due to Core issue 1430 [1] and is used | |||||
//! as suggested by Roy Crihfield in [2]. | |||||
//! In short, this is due to language's inability to expand Ts... into | //! In short, this is due to language's inability to expand Ts... into | ||||
//! a fixed parameter list of an alias template. | //! a fixed parameter list of an alias template. | ||||
//! | //! | ||||
//! \anchor link1 [1]: https://wg21.link/cwg1430 | |||||
//! \anchor link2 [2]: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59498 | |||||
//! @} | |||||
//! [1] https://wg21.link/cwg1430\n | |||||
//! [2] https://gcc.gnu.org/bugzilla/show_bug.cgi?id=59498 | |||||
} | } | ||||
//! defer alias template for F<Ts...> | |||||
/*! | |||||
* \brief | |||||
* Postpone the instantiation of a metafunction \c F with parameters \c Ts | |||||
* | |||||
* This metafunction first checks if the given arguments \c Ts are applicable to | |||||
* the metafunction \c F and if so nest inside (a layer deeper) the <em>metafunction call</em>. | |||||
* | |||||
* \tparam F The metafunction | |||||
* \tparam Ts The parameters (arguments) to \c F | |||||
*/ | |||||
template<template<class...> class F, class... Ts> | template<template<class...> class F, class... Ts> | ||||
using defer = if_< | using defer = if_< | ||||
detail::is_applicable_<F, Ts...>, | |||||
detail::defer_<F, Ts...>, | |||||
details::is_applicable_<F, Ts...>, | |||||
details::defer_<F, Ts...>, | |||||
nil_ //!< Safe, nil_ is dereferencable | nil_ //!< Safe, nil_ is dereferencable | ||||
>; | >; | ||||
//! defer_i alias template for F<T, Is...> | |||||
/*! | |||||
* \brief | |||||
* Postpone the instantiation of a metafunction \c F with parameters \c Is of type \c T. | |||||
* | |||||
* This metafunction first checks if the given arguments \c Is of type \c T are applicable to | |||||
* the metafunction \c F and if so nest inside (a layer deeper) the <em>metafunction call</em>. | |||||
* | |||||
* \tparam T The type of parameters | |||||
* \tparam F The metafunction | |||||
* \tparam Is The parameters (arguments) to \c F | |||||
*/ | |||||
template <typename T, template<T...> class F, T... Is> | template <typename T, template<T...> class F, T... Is> | ||||
using defer_i = if_ < | using defer_i = if_ < | ||||
detail::is_applicable_i_<T, F, Is...>, | |||||
detail::defer_i_<T, F, Is...>, | |||||
details::is_applicable_i_<T, F, Is...>, | |||||
details::defer_i_<T, F, Is...>, | |||||
nil_ //!< Safe, nil_ is dereferencable | nil_ //!< Safe, nil_ is dereferencable | ||||
>; | >; | ||||
//! @} | //! @} | ||||
//! quote | |||||
//! \name quote | |||||
//! @{ | //! @{ | ||||
/*! | /*! | ||||
* quote deferred is a higher-order primitive that wraps an n-ary Metafunction | |||||
* \brief | |||||
* Wraps an n-ary Metafunction \c F to a Metafunction Class using meta::defer<> | |||||
* | |||||
* quote is a higher-order primitive that wraps an n-ary Metafunction | |||||
* to create a corresponding Metafunction Class (Invocable) using defer<> to | * to create a corresponding Metafunction Class (Invocable) using defer<> to | ||||
* postpone the evaluation of Metafunction. This is a safe version of \c wrap<>. | |||||
* postpone the evaluation of Metafunction. This is a safe version of \c wrap<>.\n | |||||
* Again this way we can pass Metafunctions as types to other metafunctions and let | * Again this way we can pass Metafunctions as types to other metafunctions and let | ||||
* them \c invoke the inner templated apply | * them \c invoke the inner templated apply | ||||
* | |||||
* \tparam F The metafunction to wrap | |||||
*/ | */ | ||||
template <template <typename...> class F> | template <template <typename...> class F> | ||||
struct quote { | struct quote { | ||||
@@ -238,7 +290,21 @@ namespace meta{ | |||||
>; | >; | ||||
}; | }; | ||||
//! Wrap a template \p F taking literal constants of type \p T into an Invokable | |||||
/*! | |||||
* \brief | |||||
* Wraps an n-ary Metafunction \c F taking literal constants of type \c T | |||||
* to a Metafunction Class using meta::defer<> | |||||
* | |||||
* quote is a higher-order primitive that wraps an n-ary Metafunction | |||||
* to create a corresponding Metafunction Class (Invocable) using defer<> to | |||||
* postpone the evaluation of Metafunction. This is a safe version of \c wrap<>.\n | |||||
* Again this way we can pass Metafunctions as types to other metafunctions and let | |||||
* them \c invoke the inner templated apply | |||||
* | |||||
* \tparam T Type of integral constants | |||||
* \tparam F The metafunction to wrap | |||||
*/ | |||||
template <typename T, template <T...> class F> | template <typename T, template <T...> class F> | ||||
struct quote_i { | struct quote_i { | ||||
// requires meta::Integral | // requires meta::Integral | ||||
@@ -249,9 +315,9 @@ namespace meta{ | |||||
}; | }; | ||||
//! @} | //! @} | ||||
//! compose | |||||
//! \name compose | |||||
//! @{ | //! @{ | ||||
namespace detail { | |||||
namespace details { | |||||
template <template <typename...> class... Fns> struct compose_f_ {}; | template <template <typename...> class... Fns> struct compose_f_ {}; | ||||
// recursive call to all invokes | // recursive call to all invokes | ||||
@@ -292,12 +358,13 @@ namespace meta{ | |||||
} | } | ||||
/*! | /*! | ||||
* Create an invocable from other invocables(quoted metafunctions) by composition. | |||||
* \brief | |||||
* Create an invocable from other invocables(quoted metafunctions) by composition. | |||||
* \note | * \note | ||||
* This implies from N invocables in \p Fns the first N-1 has to be unary. | * This implies from N invocables in \p Fns the first N-1 has to be unary. | ||||
* Thats because of the "return" type of metafunction. They can only return one | * Thats because of the "return" type of metafunction. They can only return one | ||||
* type. So for n-ary invocables in the N-1 places the typelist<> is the solution. | * type. So for n-ary invocables in the N-1 places the typelist<> is the solution. | ||||
* \example | |||||
* | |||||
* \code | * \code | ||||
* static_assert( std::is_same< | * static_assert( std::is_same< | ||||
* invoke<compose<quote<F1>, quote<F2>, quote<F3>>, int>, F1<F2<F3<int>>> | * invoke<compose<quote<F1>, quote<F2>, quote<F3>>, int>, F1<F2<F3<int>>> | ||||
@@ -305,15 +372,16 @@ namespace meta{ | |||||
* \endcode | * \endcode | ||||
*/ | */ | ||||
template <typename... Fns> | template <typename... Fns> | ||||
using compose = detail::compose_<Fns...>; | |||||
using compose = details::compose_<Fns...>; | |||||
/*! | /*! | ||||
* Create an invocable from other metafunctions by composition. | |||||
* \brief | |||||
* Create an invocable from other metafunctions by composition. | |||||
* \note | * \note | ||||
* This implies from N invocables in \p Fns the first N-1 has to be unary. | * This implies from N invocables in \p Fns the first N-1 has to be unary. | ||||
* Thats because of the "return" type of metafunction. They can only return one | * Thats because of the "return" type of metafunction. They can only return one | ||||
* type. So for n-ary invocables in the N-1 places the typelist<> is the solution. | * type. So for n-ary invocables in the N-1 places the typelist<> is the solution. | ||||
* \example | |||||
* | |||||
* \code | * \code | ||||
* static_assert( std::is_same< | * static_assert( std::is_same< | ||||
* invoke<compose_f<F1, F2, F3>, int>, F1 <F2 <F3 <int>>> | * invoke<compose_f<F1, F2, F3>, int>, F1 <F2 <F3 <int>>> | ||||
@@ -321,12 +389,12 @@ namespace meta{ | |||||
* \endcode | * \endcode | ||||
*/ | */ | ||||
template <template <typename...> class... Fns> | template <template <typename...> class... Fns> | ||||
using compose_f = detail::compose_f_<Fns...>; | |||||
using compose_f = details::compose_f_<Fns...>; | |||||
//! @} | //! @} | ||||
/*! | /*! | ||||
* Applies the invocable \p Fn by binding the arguments \p Ts | |||||
* to the front of \p Fn. | |||||
* \brief | |||||
* Applies the invocable \p Fn by binding the arguments \p Ts to the front of \p Fn. | |||||
*/ | */ | ||||
template<typename Fn, typename... Ts> | template<typename Fn, typename... Ts> | ||||
struct bind_front { | struct bind_front { | ||||
@@ -335,8 +403,8 @@ namespace meta{ | |||||
}; | }; | ||||
/*! | /*! | ||||
* Applies the Invocable \p Fn by binding the arguments \p Ts | |||||
* to the back of \p Fn. | |||||
* \brief | |||||
* Applies the Invocable \p Fn by binding the arguments \p Ts to the back of \p Fn. | |||||
*/ | */ | ||||
template<typename Fn, typename... Ts> | template<typename Fn, typename... Ts> | ||||
struct bind_back { | struct bind_back { | ||||
@@ -362,7 +430,6 @@ namespace meta{ | |||||
}} | }} | ||||
//! @} | |||||
//! @} | //! @} | ||||
#endif /* __utl_meta_invoke_h__ */ | #endif /* __utl_meta_invoke_h__ */ |
@@ -1,30 +1,44 @@ | |||||
/*! | /*! | ||||
* \file /utl/meta/meta.h | |||||
* \brief Include all meta library | |||||
* \file utl/meta/meta.h | |||||
* \brief Meta library forward header | |||||
*/ | |||||
#ifndef __utl_meta_meta_h__ | |||||
#define __utl_meta_meta_h__ | |||||
/*! \defgroup meta Meta | |||||
* An embedded metaprogramming library for uTL. | |||||
* | * | ||||
* Copyright (C) 2018-2019 Christos Choutouridis | |||||
* uTL::meta is a simple metaprogramming library used widely inside uTL. | |||||
* The lib is provided to the end user via namespace \c utl::meta | |||||
* The library assembles: | |||||
* | * | ||||
* This program is free software: you can redistribute it and/or modify | |||||
* it under the terms of the GNU Lesser General Public License as | |||||
* published by the Free Software Foundation, either version 3 | |||||
* of the License, or (at your option) any later version. | |||||
* - integral constant based, operation and arithmetic functionality\n | |||||
* meta defines wrappers for all of integral types such as \c int, \c long, \c char, \c uint32_t etc... | |||||
* and also facilities to emulate: | |||||
* 1. <b>conditional (if)</b> | |||||
* 2. <b>logical operations</b> like \c or, \c and, \c not, \c bitor, \c bitand etc... | |||||
* 3. <b>math operations</b> like \c add, \c sub, \c modulo | |||||
* 4. <b>comparison operations</b> like \c equal, \c not_equal etc... | |||||
* | * | ||||
* This program is distributed in the hope that it will be useful, | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
* GNU Lesser General Public License for more details. | |||||
* All of these operate on integral types. | |||||
* | * | ||||
* You should have received a copy of the GNU Lesser General Public License | |||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||||
* - <b>SFINAE</b> wrappers as syntactic sugar to the rest of the uTL. | |||||
* | * | ||||
* - Walter's Brown <b>detection idiom</b> to help uTL concept implementation. | |||||
* | |||||
* - <b>Higher order</b> metafunction tools for composition.\n | |||||
* This module provides tools such as \c wrap, \c compose, \c fold, \c bind etc... The user can | |||||
* wrap metafunctions as types and pass them around to other metafunctions. The evaluation | |||||
* of these functions can be done both in aggressive or lazy maner using tools such as \c eval or \c invoke | |||||
* | |||||
* - <b>typelist "container"</b> implementation.\n | |||||
* Typelist is a container like template type holding the parameter list as items in the container. | |||||
* This facility has also all the expected eco-system of functions like \c push_front, | |||||
* \c push_back, \c at etc... | |||||
*/ | */ | ||||
#ifndef __utl_meta_meta_h__ | |||||
#define __utl_meta_meta_h__ | |||||
#include <utl/meta/integral.h> | |||||
#include <utl/meta/selection.h> | |||||
#include <utl/meta/operations.h> | |||||
#include <utl/meta/useif.h> | |||||
#include <utl/meta/basic.h> | |||||
#include <utl/meta/sfinae.h> | |||||
#include <utl/meta/typelist.h> | #include <utl/meta/typelist.h> | ||||
#include <utl/meta/detection.h> | #include <utl/meta/detection.h> | ||||
#include <utl/meta/invoke.h> | #include <utl/meta/invoke.h> | ||||
@@ -1,227 +0,0 @@ | |||||
/*! | |||||
* \file operations.h | |||||
* \brief Integral constant operations and logical operations | |||||
* | |||||
* Copyright (C) 2018-2019 Christos Choutouridis | |||||
* | |||||
* This program is free software: you can redistribute it and/or modify | |||||
* it under the terms of the GNU Lesser General Public License as | |||||
* published by the Free Software Foundation, either version 3 | |||||
* of the License, or (at your option) any later version. | |||||
* | |||||
* This program is distributed in the hope that it will be useful, | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
* GNU Lesser General Public License for more details. | |||||
* | |||||
* You should have received a copy of the GNU Lesser General Public License | |||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||||
*/ | |||||
#ifndef __utl_meta_operations_h__ | |||||
#define __utl_meta_operations_h__ | |||||
#include <utl/core/impl.h> | |||||
#include <utl/meta/selection.h> | |||||
/*! | |||||
* \ingroup meta | |||||
* \defgroup logic | |||||
* logic operators and type relations support | |||||
*/ | |||||
//! @{ | |||||
namespace utl { | |||||
namespace meta{ | |||||
/*! | |||||
* Logical relation for types | |||||
*/ | |||||
//! @{ | |||||
//! Negate the *bool* constant parameter | |||||
template <bool B> | |||||
using not_c = bool_<!B>; | |||||
//! not | |||||
template<typename _Tp> | |||||
using not_ = not_c<_Tp::type::value>; | |||||
//! OR implementation | |||||
//! @{ | |||||
namespace detail { | |||||
template<typename...> struct _or_; | |||||
template<> | |||||
struct _or_<> : false_ { }; | |||||
template<typename _T1> | |||||
struct _or_<_T1> : _T1 { }; | |||||
template<typename _T1, typename _T2> | |||||
struct _or_ <_T1, _T2> | |||||
: if_<_T1, _T1, _T2> { }; | |||||
template<typename _T1, typename _T2, typename _T3, typename... _Tn> | |||||
struct _or_<_T1, _T2, _T3, _Tn...> | |||||
: if_<_T1, _T1, _or_<_T2, _T3, _Tn...>> { }; | |||||
} | |||||
template <typename... _Ts> | |||||
using or_ = eval<detail::_or_<_Ts...>>; | |||||
//! @} | |||||
//! AND implementation | |||||
//! @{ | |||||
namespace detail { | |||||
template<typename...> struct _and_; | |||||
template<> | |||||
struct _and_<> | |||||
: true_ { }; | |||||
template<typename _T1> | |||||
struct _and_ <_T1> | |||||
: _T1 { }; | |||||
template<typename _T1, typename _T2> | |||||
struct _and_<_T1, _T2> | |||||
: if_<_T1, _T2, _T1> { }; | |||||
template<typename _T1, typename _T2, typename _T3, typename... _Tn> | |||||
struct _and_<_T1, _T2, _T3, _Tn...> | |||||
: if_<_T1, _and_<_T2, _T3, _Tn...>, _T1> { }; | |||||
} | |||||
template <typename... _Ts> | |||||
using and_ = eval<detail::_and_<_Ts...>>; | |||||
//! @} | |||||
//! same | |||||
//! @{ | |||||
template<typename _T1, typename _T2> | |||||
struct same_ : false_ { }; | |||||
template<typename _Tp> | |||||
struct same_ <_Tp, _Tp> : true_ { }; | |||||
//! @} | |||||
//! not same | |||||
//! @{ | |||||
template<typename _T1, typename _T2> | |||||
using not_same_ = not_<eval<same_<_T1, _T2>>>; | |||||
//! @} | |||||
//! @} | |||||
}} | |||||
//! @} | |||||
/*! | |||||
* \ingroup meta | |||||
* \defgroup integral operators | |||||
* Type arithmetic and operators | |||||
*/ | |||||
//! @{ | |||||
namespace utl { | |||||
namespace meta { | |||||
/*! | |||||
* Math operations | |||||
* requires IntegralConstant(_Tp) | |||||
*/ | |||||
//! @{ | |||||
//! Negation | |||||
template <typename _Tp> | |||||
using negate = integral_<decltype(-_Tp()), -_Tp()>; | |||||
//! Addition | |||||
template <typename _Tp1, typename _Tp2> | |||||
using add = integral_< | |||||
decltype(_Tp1() + _Tp2()), | |||||
_Tp1() + _Tp2() | |||||
>; | |||||
//! Multiplication | |||||
template <typename _Tp1, typename _Tp2> | |||||
using mult = integral_< | |||||
decltype(_Tp2() * _Tp2()), | |||||
_Tp1() * _Tp2() | |||||
>; | |||||
//! Division | |||||
template <typename _Tp1, typename _Tp2> | |||||
using divide = integral_< | |||||
decltype(_Tp2() / _Tp2()), | |||||
_Tp1() / _Tp2() | |||||
>; | |||||
//! Modulo | |||||
template <typename _Tp1, typename _Tp2> | |||||
using modulo = integral_< | |||||
decltype(_Tp1() % _Tp2()), | |||||
_Tp1() % _Tp2() | |||||
>; | |||||
//! Substruction | |||||
template <typename _Tp1, typename _Tp2> | |||||
using sub = add<_Tp1, negate<_Tp2>>; | |||||
//! Increase | |||||
template <typename _Tp> | |||||
using inc = add<_Tp, int_<1>>; | |||||
//! decrease | |||||
template <typename _Tp> | |||||
using dec = add<_Tp, int_<-1>>; | |||||
//! @} | |||||
/*! | |||||
* Comparison operations | |||||
* requires IntegralConstant(_Tp) | |||||
*/ | |||||
//! @{ | |||||
//! \return a true-valued Integral Constant if _Tp1 and _Tp2 are equal. | |||||
template <typename _Tp1, typename _Tp2> using comp_eq = bool_<_Tp1() == _Tp2()>; | |||||
//! \return a true-valued Integral Constant if _Tp1 is less than _Tp2. | |||||
template <typename _Tp1, typename _Tp2> using comp_lt = bool_<(_Tp1() < _Tp2())>; | |||||
//! Not equal | |||||
template <typename _Tp1, typename _Tp2> using comp_ne = not_<comp_eq<_Tp1, _Tp2>>; | |||||
//! Greater than | |||||
template <typename _Tp1, typename _Tp2> using comp_gt = comp_lt <_Tp2, _Tp1>; | |||||
//! Less or equal | |||||
template <typename _Tp1, typename _Tp2> using comp_le = not_<comp_lt<_Tp2, _Tp1>>; | |||||
//! Greater or equal | |||||
template <typename _Tp1, typename _Tp2> using comp_ge = not_<comp_lt<_Tp1, _Tp2>>; | |||||
//! @} | |||||
/*! | |||||
* Bitwise operations | |||||
* requires IntegralConstant(_Tp) | |||||
*/ | |||||
//! @{ | |||||
//! \return bitwise not (~) operation of its argument. | |||||
template <typename _T> using bitnot_ = integral_<typename _T::value_type, (typename _T::value_type)(~_T())>; | |||||
//! \return bitwise and (&) operation of its arguments | |||||
template <typename _Tp1, typename _Tp2> | |||||
using bitand_ = integral_<decltype(_Tp1() & _Tp2()), _Tp1() & _Tp2()>; | |||||
//! \return bitwise or (|) operation of its arguments. | |||||
template <typename _Tp1, typename _Tp2> | |||||
using bitor_ = integral_<decltype(_Tp1() | _Tp2()), _Tp1() | _Tp2()>; | |||||
//! \return bitwise xor (^) operation of its arguments. | |||||
template <typename _Tp1, typename _Tp2> | |||||
using bitxor_ = integral_<decltype(_Tp1() ^ _Tp2()), _Tp1() ^ _Tp2()>; | |||||
//! \return the result of bitwise shift left (<<) operation on _Tp. | |||||
template <typename _Tp, typename shift> | |||||
using shift_left = integral_<typename _Tp::value_type, (typename _Tp::value_type)(_Tp() << shift())>; | |||||
//! \return the result of bitwise shift right (>>) operation on _Tp. | |||||
template <typename _Tp, typename shift> | |||||
using shift_right = integral_<typename _Tp::value_type, (typename _Tp::value_type)(_Tp() >> shift())>; | |||||
//! @} | |||||
}} | |||||
//!@} | |||||
#endif /* __utl_meta_operations_h__ */ |
@@ -1,86 +0,0 @@ | |||||
/*! | |||||
* \file selection.h | |||||
* \brief Template meta-programming type selections. | |||||
* | |||||
* Copyright (C) 2018-2019 Christos Choutouridis | |||||
* | |||||
* This program is free software: you can redistribute it and/or modify | |||||
* it under the terms of the GNU Lesser General Public License as | |||||
* published by the Free Software Foundation, either version 3 | |||||
* of the License, or (at your option) any later version. | |||||
* | |||||
* This program is distributed in the hope that it will be useful, | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
* GNU Lesser General Public License for more details. | |||||
* | |||||
* You should have received a copy of the GNU Lesser General Public License | |||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||||
*/ | |||||
#ifndef __utl_meta_selection_h__ | |||||
#define __utl_meta_selection_h__ | |||||
#include <utl/core/impl.h> | |||||
#include <utl/meta/integral.h> | |||||
/*! | |||||
* \ingroup meta | |||||
* \defgroup type selection | |||||
* Type selection support header | |||||
*/ | |||||
//! @{ | |||||
namespace utl { | |||||
namespace meta{ | |||||
/*! | |||||
* Type selection | |||||
*/ | |||||
//! @{ | |||||
//! if_, if_c | |||||
//! @{ | |||||
namespace detail { | |||||
template <bool If, typename...> | |||||
struct if_c_ { | |||||
using type = nil_; //!< avoid ill formed result | |||||
}; | |||||
template<typename Then> | |||||
struct if_c_<true, Then> { | |||||
using type = Then; | |||||
}; | |||||
template<typename Then, typename Else> | |||||
struct if_c_<true, Then, Else> { | |||||
using type = Then; | |||||
}; | |||||
template<typename Then, typename Else> | |||||
struct if_c_<false, Then, Else> { | |||||
using type = Else; | |||||
}; | |||||
} | |||||
//! Select one type or another depending on a compile-time Boolean. | |||||
template <bool B, typename... Args> | |||||
using if_c = eval<detail::if_c_<B, Args...>>; | |||||
//! Select one type or another depending on a compile-time Boolean type | |||||
template <typename If, typename... Args> | |||||
using if_ = if_c<If::type::value, Args...>; | |||||
//! @} | |||||
/*! | |||||
* Named type selectors | |||||
*/ | |||||
//! @{ | |||||
//! Select the first type of a type sequence | |||||
template <typename T1, typename ...> using first_of = T1; | |||||
//! Select the second type of a type sequence | |||||
template <typename T1, typename T2, typename ...> using second_of = T2; | |||||
//! @} | |||||
}} | |||||
//! @} | |||||
#endif /* __utl_meta_selection_h__ */ |
@@ -1,68 +1,79 @@ | |||||
/*! | /*! | ||||
* \file sfinae.h | * \file sfinae.h | ||||
* \brief Template meta-programming SFINAE helpers | * \brief Template meta-programming SFINAE helpers | ||||
* | |||||
* Copyright (C) 2018-2019 Christos Choutouridis | |||||
* | |||||
* This program is free software: you can redistribute it and/or modify | |||||
* it under the terms of the GNU Lesser General Public License as | |||||
* published by the Free Software Foundation, either version 3 | |||||
* of the License, or (at your option) any later version. | |||||
* | |||||
* This program is distributed in the hope that it will be useful, | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
* GNU Lesser General Public License for more details. | |||||
* | |||||
* You should have received a copy of the GNU Lesser General Public License | |||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||||
*/ | */ | ||||
#ifndef __utl_meta_sfinae_h__ | #ifndef __utl_meta_sfinae_h__ | ||||
#define __utl_meta_sfinae_h__ | #define __utl_meta_sfinae_h__ | ||||
#include <utl/core/impl.h> | #include <utl/core/impl.h> | ||||
#include <utl/meta/basic.h> | |||||
#include <type_traits> | #include <type_traits> | ||||
/*! | /*! | ||||
* \ingroup meta | * \ingroup meta | ||||
* \defgroup sfinae | |||||
* \defgroup sfinae SFINAE | |||||
* conditional use support header. | * conditional use support header. | ||||
*/ | */ | ||||
//! @{ | //! @{ | ||||
namespace utl { | namespace utl { | ||||
namespace meta { | namespace meta { | ||||
//! Tool to enable a partial specialization only if a boolean condition is true. | |||||
//! \name enable_if from STL | |||||
//! @{ | |||||
//! enable_if, imported from stl | |||||
template <bool If, typename _Tp = void> using enable_if = std::enable_if<If, _Tp>; | |||||
//! alias template for enable_if | |||||
template<bool If, typename _Tp = void> using enable_if_t = eval< enable_if<If, _Tp> >; | |||||
//! @} | |||||
//! \name when implementation | |||||
//! @{ | //! @{ | ||||
namespace detail { | |||||
namespace details { | |||||
// template <typename... T> | // template <typename... T> | ||||
// struct dev_null { using type = dev_null; }; //< Same as typelist | // struct dev_null { using type = dev_null; }; //< Same as typelist | ||||
template <bool If> struct when_ { }; | template <bool If> struct when_ { }; | ||||
template <> struct when_<true> { using type = void; }; | template <> struct when_<true> { using type = void; }; | ||||
} | } | ||||
//! Tool to enable a partial specialization only if a boolean condition is true. | |||||
//! Well formed only if \p If is true | //! Well formed only if \p If is true | ||||
template <bool If> | template <bool If> | ||||
using when = eval< detail::when_<If> >; | |||||
using when = eval< details::when_<If> >; | |||||
// //! Well formed only if all of \p Ifs are \c true | // //! Well formed only if all of \p Ifs are \c true | ||||
// template <bool ...Ifs> | // template <bool ...Ifs> | ||||
// using when_all = detail::dev_null< | |||||
// using when_all = details::dev_null< | |||||
// when<Ifs>... | // when<Ifs>... | ||||
// >; | // >; | ||||
//! @} | //! @} | ||||
//! enable_if | |||||
//! @{ | |||||
//! If same type resolves to _Ret, else SFINAE | |||||
template <typename _T1, typename _T2, typename _Ret =_T1> | |||||
using use_if_same_t = enable_if_t< | |||||
same_<_T1, _T2>::value, _Ret | |||||
>; | |||||
//! If not same type resolves to _Ret, else SFINAE | |||||
template <typename _T1, typename _T2, typename _Ret =_T1> | |||||
using use_if_not_same_t = enable_if_t< | |||||
!same_<_T1, _T2>::value, _Ret | |||||
>; | |||||
//! If any type (_T1 or _T2) type resolves to _Ret, else to SFINAE | |||||
template <typename T1, typename... Ts> | |||||
using use_if_any_t = enable_if_t< | |||||
or_<T1, Ts...>::value, T1 | |||||
>; | |||||
//! enable_if, imported from stl | |||||
template <bool If, typename _Tp = void> using enable_if = std::enable_if<If, _Tp>; | |||||
//! If both type (_T1 and _T2) type resolves to _Ret, else to SFINAE | |||||
template <typename T1, typename... Ts> | |||||
using use_if_all_t = enable_if_t< | |||||
and_<T1, Ts...>::value, T1 | |||||
>; | |||||
//! alias template for enable_if | |||||
template<bool If, typename _Tp = void> using enable_if_t = eval< enable_if<If, _Tp> >; | |||||
//! @} | |||||
}} | }} | ||||
@@ -1,33 +1,42 @@ | |||||
/*! | /*! | ||||
* \file typelist.h | * \file typelist.h | ||||
* \brief A template parameter "container" | * \brief A template parameter "container" | ||||
* | |||||
* Copyright (C) 2018-2019 Christos Choutouridis | |||||
* | |||||
* This program is free software: you can redistribute it and/or modify | |||||
* it under the terms of the GNU Lesser General Public License as | |||||
* published by the Free Software Foundation, either version 3 | |||||
* of the License, or (at your option) any later version. | |||||
* | |||||
* This program is distributed in the hope that it will be useful, | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
* GNU Lesser General Public License for more details. | |||||
* | |||||
* You should have received a copy of the GNU Lesser General Public License | |||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||||
*/ | */ | ||||
#ifndef __utl_meta_typelist_h__ | #ifndef __utl_meta_typelist_h__ | ||||
#define __utl_meta_typelist_h__ | #define __utl_meta_typelist_h__ | ||||
#include <utl/core/impl.h> | #include <utl/core/impl.h> | ||||
#include <utl/meta/integral.h> | |||||
#include <utl/meta/basic.h> | |||||
#include <utl/meta/detection.h> | #include <utl/meta/detection.h> | ||||
#include <utl/meta/invoke.h> | #include <utl/meta/invoke.h> | ||||
#include <utl/meta/sfinae.h> | #include <utl/meta/sfinae.h> | ||||
/*! | /*! | ||||
* \ingroup meta | * \ingroup meta | ||||
* \defgroup typelist | |||||
* \defgroup typelist typelist | |||||
* | |||||
* The idea came from MPL's sequence concept [1] and from N4115 [2]. | |||||
* In addition to N4115's name "packer" we just prefer a name which is an object, not a subject. | |||||
* This way the name gives the feeling of a container and smells like Python.\n | |||||
* | |||||
* In addition to tuple we lack members, so typelist could serve as an empty base class, | |||||
* and an object of the ultimate type could always be instantiated | |||||
* (even if the parameter typelist contains void or some type that lacks | |||||
* a default constructor).\n | |||||
* | |||||
* \code{.cpp} | |||||
* using l1 = typelist<int, void*, double, void>; | |||||
* l1 a {}; | |||||
* \endcode | |||||
* | |||||
* boost::hana [3] suggests a more powerful scheme were type invariant structures can be used | |||||
* for metaprograming also. This lib does not need (yet) this kind of power (we afraid the | |||||
* responsibility that comes along).\n | |||||
* So a simple python-like list with some extra vector-like | |||||
* element access functionalities and no iterators is good enough(for now). | |||||
* | |||||
* [1]: https://www.boost.org/doc/ \n | |||||
* [2]: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4115.html \n | |||||
* [3]: https://github.com/boostorg/hana \n | |||||
*/ | */ | ||||
//! @{ | //! @{ | ||||
@@ -36,30 +45,8 @@ namespace meta { | |||||
/*! | /*! | ||||
* \brief | * \brief | ||||
* A class template that just holds a parameter pack. | |||||
* | |||||
* The idea came from MPL's sequence concept [\ref link1 1] and from N4115 [\ref link2 2]. | |||||
* In addition to N4115's name "packer" we just prefer a name which is object, not a subject. | |||||
* This way the name gives the feeling of a container and smells like Python. | |||||
* | |||||
* In addition to tuple we lack members, so typelist could serve as an empty base class, | |||||
* and an object of the ultimate type could always be instantiated | |||||
* (even if the parameter typelist contains void or some type that lacks | |||||
* a default constructor). | |||||
* \example | |||||
* \code | |||||
* using l1 = typelist<int, void*, double, void>; | |||||
* l1 a {}; | |||||
* \endcode | |||||
* | |||||
* boost::hana [\ref link3 3] suggests a more powerful scheme were type invariant structures can be used | |||||
* for metaprograming also. This lib does not need (yet) this kind of power (we afraid the | |||||
* responsibility that comes along). So a simple python-like list with some extra vector-like | |||||
* element access functionalities and no iterators is good enough(for now). | |||||
* | |||||
* \anchor link1 [1]: https://www.boost.org/doc/ | |||||
* \anchor link2 [2]: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4115.html | |||||
* \anchor link3 [3]: https://github.com/boostorg/hana | |||||
* The \c typelist 's implementation container | |||||
* \tparam Ts The \a contained types | |||||
*/ | */ | ||||
template <typename... Ts> | template <typename... Ts> | ||||
struct typelist { | struct typelist { | ||||
@@ -102,8 +89,8 @@ namespace meta { | |||||
public: | public: | ||||
/*! | /*! | ||||
* Generate typelist<Ts..., Ts..., ...> of size \c N arguments. | * Generate typelist<Ts..., Ts..., ...> of size \c N arguments. | ||||
* \example | |||||
* \code | |||||
* | |||||
* \code{.cpp} | |||||
* static_assert ( | * static_assert ( | ||||
* std::is_same<typelist<int, char>::times<2>, | * std::is_same<typelist<int, char>::times<2>, | ||||
* typelist<int, char, int, char> | * typelist<int, char, int, char> | ||||
@@ -122,8 +109,8 @@ namespace meta { | |||||
* | * | ||||
* Complexity \f$ O(1) \f$. | * Complexity \f$ O(1) \f$. | ||||
* | * | ||||
* \param List A typelist | |||||
* \return The size of the typelist | |||||
* \tparam List A typelist | |||||
* \return The size of the typelist | |||||
*/ | */ | ||||
template <typename List> | template <typename List> | ||||
using size = size_<List::size()>; | using size = size_<List::size()>; | ||||
@@ -133,8 +120,8 @@ namespace meta { | |||||
* | * | ||||
* Complexity \f$ O(1) \f$. | * Complexity \f$ O(1) \f$. | ||||
* | * | ||||
* \param List A typelist | |||||
* \return Empty or not | |||||
* \tparam List A typelist | |||||
* \return Empty or not | |||||
*/ | */ | ||||
template <typename List> | template <typename List> | ||||
using empty = bool_<List::empty()>; | using empty = bool_<List::empty()>; | ||||
@@ -145,24 +132,24 @@ namespace meta { | |||||
using pair = typelist<T1, T2>; | using pair = typelist<T1, T2>; | ||||
//! repeat | |||||
//! \name repeat | |||||
//! @{ | //! @{ | ||||
/*! | /*! | ||||
* A wrapper to typelist<>::times<> utility for integer argument \p N | |||||
* A wrapper to typelist<>::times<> utility for integer argument \c N | |||||
*/ | */ | ||||
template <size_t N, typename ...Ts> | template <size_t N, typename ...Ts> | ||||
using repeat_c = typename typelist<Ts...>::template times<N>; | using repeat_c = typename typelist<Ts...>::template times<N>; | ||||
/*! | /*! | ||||
* A wrapper to typelist<>::times<> utility for integral_c argument \p N | |||||
* A wrapper to typelist<>::times<> utility for integral_c argument \c N | |||||
*/ | */ | ||||
template <typename N, typename ...Ts> | template <typename N, typename ...Ts> | ||||
using repeat = repeat_c<N::type::value, Ts...>; | using repeat = repeat_c<N::type::value, Ts...>; | ||||
//! @} | //! @} | ||||
/*! | /*! | ||||
* Apply | |||||
* \name Apply | |||||
* An analogous to apply() implementation for tuples. We just use | * An analogous to apply() implementation for tuples. We just use | ||||
* Our typelist<> and integer_sequence<> types. | * Our typelist<> and integer_sequence<> types. | ||||
*/ | */ | ||||
@@ -171,12 +158,12 @@ namespace meta { | |||||
template <typename Fn, typename Seq> | template <typename Fn, typename Seq> | ||||
struct apply_ { }; | struct apply_ { }; | ||||
//! \p Sequence == typelist<> | |||||
// Sequence == typelist<> | |||||
template<typename Fn, typename ...List> | template<typename Fn, typename ...List> | ||||
struct apply_<Fn, typelist<List...>> { | struct apply_<Fn, typelist<List...>> { | ||||
using type = invoke<Fn, List...>; | using type = invoke<Fn, List...>; | ||||
}; | }; | ||||
//! Sequence == integer_sequence<> | |||||
// Sequence == integer_sequence<> | |||||
template <typename Fn, typename T, T... Is> | template <typename Fn, typename T, T... Is> | ||||
struct apply_<Fn, integer_sequence<T, Is...>> { | struct apply_<Fn, integer_sequence<T, Is...>> { | ||||
using type = invoke<Fn, integral_<T, Is>...>; | using type = invoke<Fn, integral_<T, Is>...>; | ||||
@@ -184,14 +171,13 @@ namespace meta { | |||||
} | } | ||||
/*! | /*! | ||||
* Apply the Invocable \p Fn using the types in the type \p Seq as arguments. | |||||
* \brief | |||||
* Apply the Invocable \c Fn using the types in the type \c Seq as arguments. | |||||
* \note | * \note | ||||
* This is the opposed operation of typelist<Ts...> | |||||
* This is the opposed operation of typelist<Ts...> | |||||
* | * | ||||
* If \p Seq == typelist<> then | |||||
* Unpack typelist and apply to \c Fn | |||||
* It \p Seq == integer_sequence<> then | |||||
* Unpack and use the integral_c<> of each integer | |||||
* If \c Seq == typelist<> then unpack typelist and apply to \c Fn \n | |||||
* It \c Seq == integer_sequence<> then unpack and use the integral_c<> of each integer | |||||
*/ | */ | ||||
template <typename Fn, typename Seq> | template <typename Fn, typename Seq> | ||||
using apply = apply_impl::apply_<Fn, Seq>; | using apply = apply_impl::apply_<Fn, Seq>; | ||||
@@ -204,7 +190,7 @@ namespace meta { | |||||
/* | /* | ||||
* ========= element access ======== | * ========= element access ======== | ||||
*/ | */ | ||||
//! at: random element access | |||||
//! \name random element access | |||||
//! @{ | //! @{ | ||||
namespace at_impl { | namespace at_impl { | ||||
@@ -235,7 +221,7 @@ namespace meta { | |||||
} | } | ||||
/*! | /*! | ||||
* Return the \p N th element in the \c meta::typelist \p List. | |||||
* Return the \c N th element in the \c meta::typelist \c List. | |||||
* | * | ||||
* Complexity \f$ O(logN) \f$. | * Complexity \f$ O(logN) \f$. | ||||
*/ | */ | ||||
@@ -245,16 +231,16 @@ namespace meta { | |||||
>; | >; | ||||
/*! | /*! | ||||
* Return the \p N th element in the \c meta::typelist \p List. | |||||
* Return the \c N th element in the \c meta::typelist \c List. | |||||
* | * | ||||
* Complexity \f$ O(N) \f$. | |||||
* Complexity \f$ O(logN) \f$. | |||||
*/ | */ | ||||
template <typename List, typename N> | template <typename List, typename N> | ||||
using at = at_c<List, N::type::value>; | using at = at_c<List, N::type::value>; | ||||
//!@} | //!@} | ||||
//! front | |||||
//! \name front | |||||
//! @{ | //! @{ | ||||
namespace front_impl { | namespace front_impl { | ||||
template <typename L> | template <typename L> | ||||
@@ -266,7 +252,8 @@ namespace meta { | |||||
}; | }; | ||||
} | } | ||||
//! Return the first element in \c meta::typelist \p List. | |||||
//! Return the first element in \c meta::typelist \c List. | |||||
//! | |||||
//! Complexity \f$ O(1) \f$. | //! Complexity \f$ O(1) \f$. | ||||
template <typename List> | template <typename List> | ||||
using front = eval< | using front = eval< | ||||
@@ -274,7 +261,7 @@ namespace meta { | |||||
>; | >; | ||||
//! @} | //! @} | ||||
//! back | |||||
//! \name back | |||||
//! @{ | //! @{ | ||||
namespace back_impl { | namespace back_impl { | ||||
template <typename List> | template <typename List> | ||||
@@ -288,7 +275,8 @@ namespace meta { | |||||
}; | }; | ||||
} | } | ||||
//! Return the last element in \c meta::typelist \p List. | |||||
//! Return the last element in \c meta::typelist \c List. | |||||
//! | |||||
//! Complexity \f$ O(N) \f$. | //! Complexity \f$ O(N) \f$. | ||||
template <typename List> | template <typename List> | ||||
using back = eval< | using back = eval< | ||||
@@ -299,7 +287,7 @@ namespace meta { | |||||
* ========= typelist operations ========= | * ========= typelist operations ========= | ||||
*/ | */ | ||||
//! Concatenation | |||||
//! \name Concatenation | |||||
//! @{ | //! @{ | ||||
namespace cat_impl { | namespace cat_impl { | ||||
template <typename... Lists> | template <typename... Lists> | ||||
@@ -329,8 +317,9 @@ namespace meta { | |||||
/*! | /*! | ||||
* Transformation that concatenates several lists into a single typelist. | * Transformation that concatenates several lists into a single typelist. | ||||
* The parameters must all be instantiations of \c meta::typelist. | * The parameters must all be instantiations of \c meta::typelist. | ||||
* | |||||
* Complexity: \f$ O(N) \f$ | * Complexity: \f$ O(N) \f$ | ||||
* where \f$ N \f$ is the number of lists passed to the algorithm. | |||||
* where \f$ N \f$ is the number of lists passed to the algorithm. | |||||
*/ | */ | ||||
template <typename... Lists> | template <typename... Lists> | ||||
using cat = eval< | using cat = eval< | ||||
@@ -339,7 +328,7 @@ namespace meta { | |||||
//! @} | //! @} | ||||
//! fold<List, V, Fn>, rev_fold<List, V, Fn> | |||||
//! \name Fold | |||||
//! @{ | //! @{ | ||||
namespace fold_impl { | namespace fold_impl { | ||||
// fold<<T1, T2, T3>, V, F> == F<F<F<V, T1>, T2>, T3> | // fold<<T1, T2, T3>, V, F> == F<F<F<V, T1>, T2>, T3> | ||||
@@ -368,16 +357,17 @@ namespace meta { | |||||
} | } | ||||
/*! | /*! | ||||
* transform the \p List to a new one by doing a left fold using binary Invocable \p Fn | |||||
* and initial value \p V | |||||
* transform the \c List to a new one by doing a left fold using binary Invocable \c Fn | |||||
* and initial value \c V | |||||
* | |||||
* Complexity \f$ O(N) \f$ | * Complexity \f$ O(N) \f$ | ||||
* \example | |||||
* \code{.cpp} | |||||
* fold<typelist<T1, T2, T3>, V, F> == F<F<F<V, T1>, T2>, T3> | * fold<typelist<T1, T2, T3>, V, F> == F<F<F<V, T1>, T2>, T3> | ||||
* \example | |||||
* fold<typelist<>, V, F> == V | * fold<typelist<>, V, F> == V | ||||
* \param List The list to fold | |||||
* \param V The initial item feeded to Fn | |||||
* \param Fn The binary Invocable | |||||
* \endcode | |||||
* \tparam List The list to fold | |||||
* \tparam V The initial item feeded to Fn | |||||
* \tparam Fn The binary Invocable | |||||
*/ | */ | ||||
template <typename List, typename V, typename Fn> | template <typename List, typename V, typename Fn> | ||||
using fold = eval<fold_impl::fold_<List, V, Fn>>; | using fold = eval<fold_impl::fold_<List, V, Fn>>; | ||||
@@ -421,16 +411,17 @@ namespace meta { | |||||
} | } | ||||
/*! | /*! | ||||
* transform the \p List to a new one by doing a right fold using binary Invocable \p Fn | |||||
* and initial value \p V | |||||
* transform the \c List to a new one by doing a right fold using binary Invocable \c Fn | |||||
* and initial value \c V | |||||
* | |||||
* Complexity \f$ O(N) \f$ | * Complexity \f$ O(N) \f$ | ||||
* \example | |||||
* \code{.cpp} | |||||
* rev_fold<typelist<T1, T2, T3>, V, F> == F<T1, F<T2, F<T3, V>>> | * rev_fold<typelist<T1, T2, T3>, V, F> == F<T1, F<T2, F<T3, V>>> | ||||
* \example | |||||
* rev_fold<typelist<>, V, F> == V | * rev_fold<typelist<>, V, F> == V | ||||
* \param List The list to fold | |||||
* \param V The initial item fed to Fn | |||||
* \param Fn The binary Invocable | |||||
* \endcode | |||||
* \tparam List The list to fold | |||||
* \tparam V The initial item fed to Fn | |||||
* \tparam Fn The binary Invocable | |||||
*/ | */ | ||||
template <typename List, typename V, typename Fn> | template <typename List, typename V, typename Fn> | ||||
using rev_fold = eval< | using rev_fold = eval< | ||||
@@ -439,7 +430,8 @@ namespace meta { | |||||
//! @} | //! @} | ||||
/*! | /*! | ||||
* Return a new \c typelist by adding the elements \p Ts to the front of \p List. | |||||
* Return a new \c typelist by adding the elements \c Ts to the front of \c List. | |||||
* | |||||
* Complexity \f$ O(1) \f$ | * Complexity \f$ O(1) \f$ | ||||
*/ | */ | ||||
template <typename List, typename... Ts> | template <typename List, typename... Ts> | ||||
@@ -450,7 +442,8 @@ namespace meta { | |||||
>; | >; | ||||
/*! | /*! | ||||
* Return a new \c typelist by adding the elements \p Ts to the back of \p List. | |||||
* Return a new \c typelist by adding the elements \c Ts to the back of \c List. | |||||
* | |||||
* Complexity \f$ O(1) \f$ | * Complexity \f$ O(1) \f$ | ||||
*/ | */ | ||||
template <typename List, typename... Ts> | template <typename List, typename... Ts> | ||||
@@ -460,7 +453,7 @@ namespace meta { | |||||
> | > | ||||
>; | >; | ||||
//! reverse | |||||
//! \name reverse | |||||
//! @{ | //! @{ | ||||
namespace reverse_impl { | namespace reverse_impl { | ||||
template <typename List, typename V = typelist<>> | template <typename List, typename V = typelist<>> | ||||
@@ -470,7 +463,8 @@ namespace meta { | |||||
} | } | ||||
/*! | /*! | ||||
* Return a new \c typelist by reversing the elements in the list \p List. | |||||
* Return a new \c typelist by reversing the elements in the list \c List. | |||||
* | |||||
* Complexity \f$ O(N) \f$ | * Complexity \f$ O(N) \f$ | ||||
*/ | */ | ||||
template <typename List> | template <typename List> | ||||
@@ -479,7 +473,7 @@ namespace meta { | |||||
>; | >; | ||||
//! @} | //! @} | ||||
//! pop_front | |||||
//! \name pop_front | |||||
//! @{ | //! @{ | ||||
namespace pop_front_impl { | namespace pop_front_impl { | ||||
template <typename List> | template <typename List> | ||||
@@ -493,7 +487,8 @@ namespace meta { | |||||
/*! | /*! | ||||
* Return a new \c typelist by removing the first element from the | * Return a new \c typelist by removing the first element from the | ||||
* front of \p List. | |||||
* front of \c List. | |||||
* | |||||
* Complexity \f$ O(1) \f$ | * Complexity \f$ O(1) \f$ | ||||
*/ | */ | ||||
template <typename List> | template <typename List> | ||||
@@ -502,7 +497,7 @@ namespace meta { | |||||
>; | >; | ||||
//! @} | //! @} | ||||
//! pop_back | |||||
//! \name pop_back | |||||
//! @{ | //! @{ | ||||
namespace pop_back_impl { | namespace pop_back_impl { | ||||
template <typename List> | template <typename List> | ||||
@@ -514,7 +509,8 @@ namespace meta { | |||||
} | } | ||||
/*! | /*! | ||||
* Return a new \c typelist by removing the last element from the \p List. | |||||
* Return a new \c typelist by removing the last element from the \c List. | |||||
* | |||||
* Complexity \f$ O(N) \f$. | * Complexity \f$ O(N) \f$. | ||||
* \note | * \note | ||||
* This operation, in addition from other push/pop operations, is | * This operation, in addition from other push/pop operations, is | ||||
@@ -526,7 +522,7 @@ namespace meta { | |||||
>; | >; | ||||
//! @} | //! @} | ||||
//! Transform | |||||
//! \name Transform | |||||
//! @{ | //! @{ | ||||
namespace transform_impl { | namespace transform_impl { | ||||
template <typename, typename = void> | template <typename, typename = void> | ||||
@@ -554,8 +550,7 @@ namespace meta { | |||||
* and return the resulting typelist | * and return the resulting typelist | ||||
* | * | ||||
* Complexity \f$ O(N) \f$. | * Complexity \f$ O(N) \f$. | ||||
* \example | |||||
* \code | |||||
* \code{.cpp} | |||||
* using l1 = typelist<char, int, ...>; | * using l1 = typelist<char, int, ...>; | ||||
* using l2 = typelist<void, double, ...>; | * using l2 = typelist<void, double, ...>; | ||||
* using r1 = transform<l1, F1>; // F1, unary invocable | * using r1 = transform<l1, F1>; // F1, unary invocable | ||||
@@ -568,7 +563,7 @@ namespace meta { | |||||
>; | >; | ||||
//! @} | //! @} | ||||
//! Transform lazy | |||||
//! \name Transform lazy | |||||
//! @{ | //! @{ | ||||
namespace transform_lazy_impl { | namespace transform_lazy_impl { | ||||
template <typename, typename = void> | template <typename, typename = void> | ||||
@@ -600,8 +595,7 @@ namespace meta { | |||||
* | * | ||||
* Complexity \f$ O(N) \f$ | * Complexity \f$ O(N) \f$ | ||||
* | * | ||||
* \example | |||||
* \code | |||||
* \code{.cpp} | |||||
* using l1 = typelist<char, int, ...>; | * using l1 = typelist<char, int, ...>; | ||||
* using l2 = typelist<void, void, ...>; | * using l2 = typelist<void, void, ...>; | ||||
* using r1 = transform<l1, F1>; // F1, unary invocable | * using r1 = transform<l1, F1>; // F1, unary invocable | ||||
@@ -615,7 +609,7 @@ namespace meta { | |||||
//! @} | //! @} | ||||
//! find_if, find | |||||
//! \name find_if, find | |||||
//! @{ | //! @{ | ||||
namespace find_if_impl { | namespace find_if_impl { | ||||
template <typename, typename, index_t> | template <typename, typename, index_t> | ||||
@@ -641,13 +635,13 @@ namespace meta { | |||||
} | } | ||||
/*! | /*! | ||||
* Search for the first \c Item on the \p List for which the predicate \p Pred | |||||
* Search for the first \c Item on the \c List for which the predicate \c Pred | |||||
* returns true_ when `eval<invoke<Pred, Item>>` | * returns true_ when `eval<invoke<Pred, Item>>` | ||||
* | * | ||||
* Complexity \f$ O(N) \f$ | * Complexity \f$ O(N) \f$ | ||||
* | * | ||||
* \param List A typelist | |||||
* \param Pred A Unary invocable predicate | |||||
* \tparam List A typelist | |||||
* \tparam Pred A Unary invocable predicate | |||||
* \return An integral constant of index_t with the location of the first match, | * \return An integral constant of index_t with the location of the first match, | ||||
* or Npos otherwise. | * or Npos otherwise. | ||||
*/ | */ | ||||
@@ -657,13 +651,13 @@ namespace meta { | |||||
>; | >; | ||||
/*! | /*! | ||||
* Search for the first occurrence of type \p T on a \p List | |||||
* Search for the first occurrence of type \c T on a \c List | |||||
*/ | */ | ||||
template <typename List, typename T> | template <typename List, typename T> | ||||
using find = find_if<List, same_as<T>>; | using find = find_if<List, same_as<T>>; | ||||
//! @} | //! @} | ||||
//! seek_if | |||||
//! \name seek_if | |||||
//! @{ | //! @{ | ||||
namespace seek_if_impl { | namespace seek_if_impl { | ||||
template <typename, typename, index_t> | template <typename, typename, index_t> | ||||
@@ -689,14 +683,14 @@ namespace meta { | |||||
} | } | ||||
/*! | /*! | ||||
* Search for the first \c Item on the \p List for which the predicate \p Pred | |||||
* returns true_ when `eval<invoke<Pred, Item>>` and return the rest of the \p List | |||||
* Search for the first \c Item on the \c List for which the predicate \c Pred | |||||
* returns true_ when `eval<invoke<Pred, Item>>` and return the rest of the \c List | |||||
* starting from that position as new typelist | * starting from that position as new typelist | ||||
* | * | ||||
* Complexity \f$ O(N) \f$ | * Complexity \f$ O(N) \f$ | ||||
* | * | ||||
* \param List A typelist | |||||
* \param Pred A Unary invocable predicate | |||||
* \tparam List A typelist | |||||
* \tparam Pred A Unary invocable predicate | |||||
* \return An integral constant with the location of the first match, on Npos otherwise | * \return An integral constant with the location of the first match, on Npos otherwise | ||||
*/ | */ | ||||
template <typename List, typename Pred> | template <typename List, typename Pred> | ||||
@@ -704,14 +698,14 @@ namespace meta { | |||||
seek_if_impl::seek_if_<List, Pred, 0> | seek_if_impl::seek_if_<List, Pred, 0> | ||||
>; | >; | ||||
/*! | /*! | ||||
* Search for the first \c Item on the \p List of type \p T and return the rest | |||||
* of the \p List starting from that position as new typelist | |||||
* Search for the first \c Item on the \c List of type \c T and return the rest | |||||
* of the \c List starting from that position as new typelist | |||||
*/ | */ | ||||
template <typename List, typename T> | template <typename List, typename T> | ||||
using seek = seek_if <List, same_as<T>>; | using seek = seek_if <List, same_as<T>>; | ||||
//! @} | //! @} | ||||
//! count_if | |||||
//! \name count_if | |||||
//! @{ | //! @{ | ||||
namespace count_if_impl { | namespace count_if_impl { | ||||
template <typename, typename, size_t> | template <typename, typename, size_t> | ||||
@@ -740,13 +734,13 @@ namespace meta { | |||||
} | } | ||||
/*! | /*! | ||||
* Count all \c Items on the \p List for which the predicate \p Pred | |||||
* Count all \c Items on the \c List for which the predicate \c Pred | |||||
* returns true_ when `eval<invoke<Pred, Item>>` | * returns true_ when `eval<invoke<Pred, Item>>` | ||||
* | * | ||||
* Complexity \f$ O(N) \f$ | * Complexity \f$ O(N) \f$ | ||||
* | * | ||||
* \param List A typelist | |||||
* \param Pred A Unary invocable predicate | |||||
* \tparam List A typelist | |||||
* \tparam Pred A Unary invocable predicate | |||||
* \return The total count of occurrences as an integral constant of size_t | * \return The total count of occurrences as an integral constant of size_t | ||||
*/ | */ | ||||
template <typename List, typename Pred> | template <typename List, typename Pred> | ||||
@@ -755,13 +749,13 @@ namespace meta { | |||||
>; | >; | ||||
/*! | /*! | ||||
* Count all occurrences of type \p T int \p List | |||||
* Count all occurrences of type \c T int \c List | |||||
*/ | */ | ||||
template <typename List, typename T> | template <typename List, typename T> | ||||
using count = count_if<List, same_as<T>>; | using count = count_if<List, same_as<T>>; | ||||
//! @} | //! @} | ||||
//! filter | |||||
//! \name filter | |||||
//! @{ | //! @{ | ||||
namespace filter_impl { | namespace filter_impl { | ||||
template <typename, typename, typename> | template <typename, typename, typename> | ||||
@@ -786,13 +780,13 @@ namespace meta { | |||||
} | } | ||||
/*! | /*! | ||||
* Return a new typelist with elements, the elements of \p List that satisfy the | |||||
* invocable \p Pred such that `eval<invoke<Pred, Item>>` is \c true_ | |||||
* Return a new typelist with elements, the elements of \c List that satisfy the | |||||
* invocable \c Pred such that `eval<invoke<Pred, Item>>` is \c true_ | |||||
* | * | ||||
* Complexity \f$ O(N) \f$ | * Complexity \f$ O(N) \f$ | ||||
* | * | ||||
* \param List The input typelist | |||||
* \param Pred A unary invocable predicate | |||||
* \tparam List The input typelist | |||||
* \tparam Pred A unary invocable predicate | |||||
*/ | */ | ||||
template <typename List, typename Pred> | template <typename List, typename Pred> | ||||
using filter = eval< | using filter = eval< | ||||
@@ -800,7 +794,7 @@ namespace meta { | |||||
>; | >; | ||||
//! @} | //! @} | ||||
//! replace | |||||
//! \name replace | |||||
//! @{ | //! @{ | ||||
namespace replace_if_impl { | namespace replace_if_impl { | ||||
template <typename, typename, typename, typename> | template <typename, typename, typename, typename> | ||||
@@ -825,14 +819,14 @@ namespace meta { | |||||
} | } | ||||
/*! | /*! | ||||
* Return a new typelist where all the instances for which the invocation of\p Pred | |||||
* returns \c true_, are replaced with \p T | |||||
* Return a new typelist where all the instances for which the invocation of\c Pred | |||||
* returns \c true_, are replaced with \c T | |||||
* | * | ||||
* Complexity \f$ O(N) \f$ | * Complexity \f$ O(N) \f$ | ||||
* | * | ||||
* \param List The input typelist | |||||
* \param Pred A unary invocable predicate | |||||
* \param T The new type to replace the item of the \p List, when eval<invoke<Pred, Item>> | |||||
* \tparam List The input typelist | |||||
* \tparam Pred A unary invocable predicate | |||||
* \tparam T The new type to replace the item of the \c List, when eval<invoke<Pred, Item>> | |||||
* returns \c true_ | * returns \c true_ | ||||
*/ | */ | ||||
template<typename List, typename Pred, typename T> | template<typename List, typename Pred, typename T> | ||||
@@ -840,8 +834,8 @@ namespace meta { | |||||
replace_if_impl::replace_if_<List, Pred, T, typelist<>> | replace_if_impl::replace_if_<List, Pred, T, typelist<>> | ||||
>; | >; | ||||
//! Alias wrapper that returns a new \c typelist where all instances of type \p T have | |||||
//! been replaced with \p U. | |||||
//! Alias wrapper that returns a new \c typelist where all instances of type \c T have | |||||
//! been replaced with \c U. | |||||
template <typename List, typename T, typename U> | template <typename List, typename T, typename U> | ||||
using replace = eval < | using replace = eval < | ||||
replace_if <List, same_as<T>, U> | replace_if <List, same_as<T>, U> | ||||
@@ -849,8 +843,8 @@ namespace meta { | |||||
//! @} | //! @} | ||||
//! Returns \c true_ if \p Pred returns \c true_ for all the elements in the \p List or if the | |||||
//! \p List is empty and \c false_ otherwise. | |||||
//! Returns \c true_ if \c Pred returns \c true_ for all the elements in the \c List or if the | |||||
//! \c List is empty and \c false_ otherwise. | |||||
template <typename List, typename Pred> | template <typename List, typename Pred> | ||||
using all_of = if_ < | using all_of = if_ < | ||||
empty <List>, | empty <List>, | ||||
@@ -860,15 +854,15 @@ namespace meta { | |||||
> | > | ||||
>; | >; | ||||
//! Returns \c true_ if \p Pred returns \c true_ for any of the elements in the \p List | |||||
//! Returns \c true_ if \c Pred returns \c true_ for any of the elements in the \c List | |||||
//! and \c false_ otherwise. | //! and \c false_ otherwise. | ||||
template <typename List, typename Pred> | template <typename List, typename Pred> | ||||
using any_of = not_< | using any_of = not_< | ||||
empty<filter <List, Pred>> | empty<filter <List, Pred>> | ||||
>; | >; | ||||
//! Returns \c true_ if \p Pred returns \c false_ for all the elements in the \p List | |||||
//! or if the \p List is empty and \c false otherwise. | |||||
//! Returns \c true_ if \c Pred returns \c false_ for all the elements in the \c List | |||||
//! or if the \c List is empty and \c false otherwise. | |||||
template <typename List, typename Pred> | template <typename List, typename Pred> | ||||
using none_of = empty< | using none_of = empty< | ||||
filter <List, Pred> | filter <List, Pred> | ||||
@@ -1,62 +0,0 @@ | |||||
/*! | |||||
* \file useif.h | |||||
* \brief Template meta-programming SFINAE helpers | |||||
* | |||||
* Copyright (C) 2018 Christos Choutouridis | |||||
* | |||||
* This program is free software: you can redistribute it and/or modify | |||||
* it under the terms of the GNU Lesser General Public License as | |||||
* published by the Free Software Foundation, either version 3 | |||||
* of the License, or (at your option) any later version. | |||||
* | |||||
* This program is distributed in the hope that it will be useful, | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
* GNU Lesser General Public License for more details. | |||||
* | |||||
* You should have received a copy of the GNU Lesser General Public License | |||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||||
*/ | |||||
#ifndef __utl_meta_useif_h__ | |||||
#define __utl_meta_useif_h__ | |||||
#include <utl/core/impl.h> | |||||
#include <utl/meta/operations.h> | |||||
#include <utl/meta/sfinae.h> | |||||
/*! | |||||
* \ingroup meta | |||||
* \defgroup sfinae | |||||
* conditional use support header. This is a SFINAE wrapper | |||||
*/ | |||||
//! @{ | |||||
namespace utl { | |||||
namespace meta { | |||||
//! If same type resolves to _Ret, else SFINAE | |||||
template <typename _T1, typename _T2, typename _Ret =_T1> | |||||
using use_if_same_t = enable_if_t< | |||||
same_<_T1, _T2>::value, _Ret | |||||
>; | |||||
//! If not same type resolves to _Ret, else SFINAE | |||||
template <typename _T1, typename _T2, typename _Ret =_T1> | |||||
using use_if_not_same_t = enable_if_t< | |||||
!same_<_T1, _T2>::value, _Ret | |||||
>; | |||||
//! If any type (_T1 or _T2) type resolves to _Ret, else to SFINAE | |||||
template <typename T1, typename... Ts> | |||||
using use_if_any_t = enable_if_t< | |||||
or_<T1, Ts...>::value, T1 | |||||
>; | |||||
//! If both type (_T1 and _T2) type resolves to _Ret, else to SFINAE | |||||
template <typename T1, typename... Ts> | |||||
using use_if_all_t = enable_if_t< | |||||
and_<T1, Ts...>::value, T1 | |||||
>; | |||||
}} | |||||
//! @} | |||||
#endif /* __utl_meta_useif_h__ */ |
@@ -1,21 +1,6 @@ | |||||
/*! | /*! | ||||
* \file utl/utility/invoke.h | * \file utl/utility/invoke.h | ||||
* \brief invoke() and invoke traits implementation | * \brief invoke() and invoke traits implementation | ||||
* | |||||
* Copyright (C) 2018-2019 Christos Choutouridis | |||||
* | |||||
* This program is free software: you can redistribute it and/or modify | |||||
* it under the terms of the GNU Lesser General Public License as | |||||
* published by the Free Software Foundation, either version 3 | |||||
* of the License, or (at your option) any later version. | |||||
* | |||||
* This program is distributed in the hope that it will be useful, | |||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||||
* GNU Lesser General Public License for more detail. | |||||
* | |||||
* You should have received a copy of the GNU Lesser General Public License | |||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. | |||||
*/ | */ | ||||
#ifndef __utl_utility_invoke_h__ | #ifndef __utl_utility_invoke_h__ | ||||
#define __utl_utility_invoke_h__ | #define __utl_utility_invoke_h__ | ||||
@@ -27,13 +12,16 @@ | |||||
#include <functional> | #include <functional> | ||||
#include <utility> | #include <utility> | ||||
//! \defgroup utility Utility | |||||
/*! | /*! | ||||
* \ingroup utility | * \ingroup utility | ||||
* \defgroup invoke | |||||
* \defgroup util_invoke Invoke | |||||
*/ | */ | ||||
//! @{ | //! @{ | ||||
namespace utl { | namespace utl { | ||||
#if !defined __cpp_lib_is_invocable | |||||
namespace detail { | namespace detail { | ||||
template <class T> | template <class T> | ||||
@@ -116,16 +104,41 @@ namespace utl { | |||||
} // namespace detail | } // namespace detail | ||||
//! Invoke a callable object (for C++14) | |||||
template<typename _Callable, typename... _Args> | |||||
inline decltype(auto) invoke(_Callable&& fn, _Args&&... args) { | |||||
//! Invoke the Callable object \c fn with the parameters args. | |||||
//! As by INVOKE(std::forward<F>(f), std::forward<Args>(args)...). | |||||
//! | |||||
//! \note | |||||
//! This implementation fills the lack of an invoke() utility for builds | |||||
//! pre-c++17. | |||||
//! | |||||
//! \param fn Callable object to be invoked | |||||
//! \param args Arguments to pass to \c fn | |||||
//! \return The return of the Callable underling functionality | |||||
//! | |||||
template<typename Callable, typename... Args> | |||||
inline decltype(auto) invoke(Callable&& fn, Args&&... args) { | |||||
return detail::invoke_impl_( | return detail::invoke_impl_( | ||||
std::forward<_Callable>(fn), std::forward<_Args>(args)... | |||||
std::forward<Callable>(fn), std::forward<Args>(args)... | |||||
); | ); | ||||
} | } | ||||
//! @} | |||||
//! std::is_invocable trait for C++11 | |||||
//! | |||||
//! \brief | |||||
//! Determines whether \c F can be invoked with the arguments \c Args.... | |||||
//! | |||||
//! Formally, determines whether invoke(declval<Fn>(), declval<ArgTypes>()...) | |||||
//! is well formed when treated as an unevaluated operand, | |||||
//! where invoke is \c Callable. | |||||
//! | |||||
//! \note | |||||
//! This implementation fills the lack of an invoke() utility for builds | |||||
//! pre-c++17. | |||||
//! | |||||
//! \tparam F The candidate type to check if its invocable | |||||
//! \tparam Args The arguments for the call | |||||
//! \return If \c F is invocable | |||||
//! \arg true Is invocable | |||||
//! \arg false Is not invocable | |||||
template <typename F, typename... Args> | template <typename F, typename... Args> | ||||
struct is_invocable : | struct is_invocable : | ||||
std::is_constructible< | std::is_constructible< | ||||
@@ -133,7 +146,19 @@ namespace utl { | |||||
std::reference_wrapper<typename std::remove_reference<F>::type> | std::reference_wrapper<typename std::remove_reference<F>::type> | ||||
> { }; | > { }; | ||||
//! std::is_invocable_r trait for C++11 | |||||
//! \brief | |||||
//! Determines whether \c F can be invoked with the arguments \c Args... | |||||
//! to yield a result that is convertible to \c R. | |||||
//! | |||||
//! Formally, determines whether invoke(declval<Fn>(), declval<ArgTypes>()...) | |||||
//! is well formed when treated as an unevaluated operand, where invoke is \c Callable. | |||||
//! | |||||
//! \tparam R The return type of invocable functionality | |||||
//! \tparam F The candidate type to check if its invocable | |||||
//! \tparam Args The arguments to pass to \c F | |||||
//! \return If \c F is invocable | |||||
//! \arg true Is invocable | |||||
//! \arg false Is not invocable | |||||
template <typename R, typename F, typename... Args> | template <typename R, typename F, typename... Args> | ||||
struct is_invocable_r : | struct is_invocable_r : | ||||
std::is_constructible< | std::is_constructible< | ||||
@@ -146,38 +171,54 @@ namespace utl { | |||||
*/ | */ | ||||
//! @{ | //! @{ | ||||
namespace detail { | namespace detail { | ||||
template<typename _Callable, typename... _Args> | |||||
template<typename Callable, typename... Args> | |||||
struct try_invoke { | struct try_invoke { | ||||
using type = decltype ( | using type = decltype ( | ||||
detail::invoke_impl_(std::declval<_Callable&&>(), std::declval<_Args&&>()...) | |||||
detail::invoke_impl_(std::declval<Callable&&>(), std::declval<Args&&>()...) | |||||
); | ); | ||||
}; | }; | ||||
template<bool B, typename _Callable, typename... _Args> | |||||
template<bool B, typename Callable, typename... Args> | |||||
struct invoke_result_ { | struct invoke_result_ { | ||||
using type = meta::nil_; | using type = meta::nil_; | ||||
}; | }; | ||||
template <typename _Callable, typename... _Args> | |||||
struct invoke_result_ <true, _Callable, _Args...> { | |||||
template <typename Callable, typename... Args> | |||||
struct invoke_result_ <true, Callable, Args...> { | |||||
using type = meta::invoke_t< | using type = meta::invoke_t< | ||||
meta::quote<try_invoke>, _Callable, _Args... | |||||
meta::quote<try_invoke>, Callable, Args... | |||||
>; | >; | ||||
}; | }; | ||||
} | } | ||||
//! invoke_result (for C++14) | |||||
template <typename _Callable, typename... _Args> | |||||
//! trait that deduces the return type of an INVOKE expression at compile time. | |||||
//! | |||||
//! \tparam Callable The candidate type to check if its invocable | |||||
//! \tparam Args The arguments to pass to \c F | |||||
//! | |||||
//! \b member \n | |||||
//! \::type The return type of the \c Callable type if invoked with the arguments Args.... | |||||
template <typename Callable, typename... Args> | |||||
using invoke_result = detail::invoke_result_< | using invoke_result = detail::invoke_result_< | ||||
is_invocable<_Callable, _Args...>::value, | |||||
_Callable, | |||||
_Args... | |||||
is_invocable<Callable, Args...>::value, | |||||
Callable, | |||||
Args... | |||||
>; | >; | ||||
//! invoke_result_t (for C++14) | |||||
template<typename _Callable, typename... _Args> | |||||
//! trait that deduces the return type of an INVOKE expression at compile time. | |||||
//! | |||||
//! \tparam Callable The candidate type to check if its invocable | |||||
//! \tparam Args The arguments to pass to \c F | |||||
//! | |||||
//! \return The type of the \c Callable type if invoked with the arguments Args.... | |||||
template<typename Callable, typename... Args> | |||||
using invoke_result_t = meta::eval < | using invoke_result_t = meta::eval < | ||||
invoke_result<_Callable, _Args...> | |||||
invoke_result<Callable, Args...> | |||||
>; | >; | ||||
//! @} | |||||
#else | |||||
#endif | |||||
} | } | ||||
//! @} | //! @} | ||||