@@ -1087,7 +1087,7 @@ CLANG_ASSISTED_PARSING = YES | |||||
# 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 = | |||||
CLANG_OPTIONS = -I../include | |||||
#--------------------------------------------------------------------------- | #--------------------------------------------------------------------------- | ||||
# Configuration options related to the alphabetical class index | # Configuration options related to the alphabetical class index | ||||
@@ -1,486 +0,0 @@ | |||||
{ | |||||
"clang": { | |||||
"clang-compilation-path": "", | |||||
"clang-dialect": "-std=c++14", | |||||
"clang-flags": [ | |||||
"" | |||||
], | |||||
"clang-parsing": false, | |||||
"clang-use-headers": true | |||||
}, | |||||
"configuration": { | |||||
"allow-sub-grouping": true, | |||||
"allow-unicode-names": false, | |||||
"always-detailed-sec": false, | |||||
"auto-link": true, | |||||
"brief-member-desc": true, | |||||
"built-in-stl-support": false, | |||||
"case-sensitive-fname": true, | |||||
"cpp-cli-support": false, | |||||
"create-subdirs": false, | |||||
"duplicate-docs": false, | |||||
"enabled-sections": [ | |||||
"" | |||||
], | |||||
"extract-all": false, | |||||
"extract-anon-namespaces": false, | |||||
"extract-local-classes": true, | |||||
"extract-local-methods": false, | |||||
"extract-package": false, | |||||
"extract-private": false, | |||||
"extract-static": false, | |||||
"file-version-filter": "", | |||||
"force-local-includes": false, | |||||
"full-path-names": true, | |||||
"generate-bug-list": true, | |||||
"generate-deprecate-list": true, | |||||
"generate-test-list": true, | |||||
"generate-todo-list": true, | |||||
"group-nested-compounds": false, | |||||
"hide-compound-ref": false, | |||||
"hide-friend-compounds": false, | |||||
"hide-in-body-docs": false, | |||||
"hide-navtree-members": false, | |||||
"hide-scope-names": false, | |||||
"hide-undoc-classes": true, | |||||
"hide-undoc-members": true, | |||||
"idl-support": true, | |||||
"inherit-docs": true, | |||||
"inline-grouped-classes": false, | |||||
"inline-info": true, | |||||
"inline-inherited-member": false, | |||||
"inline-simple-struct": false, | |||||
"internal-docs": false, | |||||
"javadoc-auto-brief": false, | |||||
"language-mapping": [ | |||||
"" | |||||
], | |||||
"layout-file": "", | |||||
"main-page-name": "", | |||||
"main-page-omit": false, | |||||
"markdown": true, | |||||
"max-init-lines": 30, | |||||
"multiline-cpp-brief": false, | |||||
"ns-alias": [ | |||||
"" | |||||
], | |||||
"qt-auto-brief": false, | |||||
"repeat-brief": true, | |||||
"separate-member-pages": false, | |||||
"short-names": false, | |||||
"show-file-page": true, | |||||
"show-grouped-members-inc": false, | |||||
"show-include-files": true, | |||||
"show-namespace-page": true, | |||||
"show-used-files": true, | |||||
"sip-support": false, | |||||
"sort-brief-docs": false, | |||||
"sort-by-scope-name": false, | |||||
"sort-class-case-sensitive": false, | |||||
"sort-constructors-first": true, | |||||
"sort-group-names": false, | |||||
"sort-member-docs": true, | |||||
"strict-sig-matching": false, | |||||
"tcl-subst": [ | |||||
"" | |||||
], | |||||
"toc-include-headers": 0, | |||||
"use-typedef-name": false | |||||
}, | |||||
"dot": { | |||||
"class-diagrams": true, | |||||
"dia-file-dirs": [ | |||||
"" | |||||
], | |||||
"dia-path": "", | |||||
"directory-graph": true, | |||||
"dot-call": false, | |||||
"dot-called-by": false, | |||||
"dot-class-graph": true, | |||||
"dot-cleanup": true, | |||||
"dot-collaboration": true, | |||||
"dot-file-dirs": [ | |||||
"" | |||||
], | |||||
"dot-font-name": "Helvetica", | |||||
"dot-font-path": "", | |||||
"dot-font-size": 10, | |||||
"dot-graph-max-depth": 0, | |||||
"dot-graph-max-nodes": 50, | |||||
"dot-hierarchy": true, | |||||
"dot-image-format": "png", | |||||
"dot-include": true, | |||||
"dot-included-by": true, | |||||
"dot-multiple-targets": false, | |||||
"dot-num-threads": 0, | |||||
"dot-path": "", | |||||
"dot-transparent": false, | |||||
"generate-legend": true, | |||||
"group-graphs": true, | |||||
"have-dot": false, | |||||
"hide-undoc-relations": true, | |||||
"interactive-svg": false, | |||||
"msc-file-dirs": [ | |||||
"" | |||||
], | |||||
"mscgen-path": "", | |||||
"plantuml-cfg-file": "", | |||||
"plantuml-inc-path": [ | |||||
"" | |||||
], | |||||
"plantuml-jar-path": "", | |||||
"template-relations": false, | |||||
"uml-limit-num-fields": 10, | |||||
"uml-look": false | |||||
}, | |||||
"doxypress-format": 1, | |||||
"doxypress-updated": "2018-Jun-30", | |||||
"external": { | |||||
"all-externals": false, | |||||
"external-groups": true, | |||||
"external-pages": true, | |||||
"generate-tagfile": "", | |||||
"perl-path": "/usr/bin/perl", | |||||
"tag-files": [ | |||||
"" | |||||
] | |||||
}, | |||||
"general": { | |||||
"abbreviate-brief": [ | |||||
"The $name class", | |||||
"The $name widget", | |||||
"The $name file", | |||||
"is", | |||||
"provides", | |||||
"specifies", | |||||
"contains", | |||||
"represents", | |||||
"a", | |||||
"an", | |||||
"the" | |||||
], | |||||
"aliases": [ | |||||
"" | |||||
], | |||||
"lookup-cache-size": 0, | |||||
"optimize-c": false, | |||||
"optimize-cplus": true, | |||||
"optimize-fortran": false, | |||||
"optimize-java": false, | |||||
"optimize-python": false, | |||||
"output-dir": "doc", | |||||
"output-language": "English", | |||||
"strip-from-inc-path": [ | |||||
"" | |||||
], | |||||
"strip-from-path": [ | |||||
"" | |||||
], | |||||
"tab-size": 4 | |||||
}, | |||||
"index": { | |||||
"alpha-index": true, | |||||
"cols-in-index": 5, | |||||
"ignore-prefix": [ | |||||
"" | |||||
] | |||||
}, | |||||
"input": { | |||||
"example-patterns": [ | |||||
"*" | |||||
], | |||||
"example-recursive": false, | |||||
"example-source": [ | |||||
"" | |||||
], | |||||
"exclude-files": [ | |||||
"" | |||||
], | |||||
"exclude-patterns": [ | |||||
"" | |||||
], | |||||
"exclude-symbols": [ | |||||
"" | |||||
], | |||||
"exclude-symlinks": false, | |||||
"filter-patterns": [ | |||||
"" | |||||
], | |||||
"filter-program": "", | |||||
"filter-source-files": false, | |||||
"filter-source-patterns": [ | |||||
"" | |||||
], | |||||
"image-path": [ | |||||
"" | |||||
], | |||||
"input-encoding": "UTF-8", | |||||
"input-patterns": [ | |||||
"*.as", | |||||
"*.c", | |||||
"*.cc", | |||||
"*.cpp", | |||||
"*.cxx", | |||||
"*.c++", | |||||
"*.cs", | |||||
"*.d", | |||||
"*.ddl", | |||||
"*.dox", | |||||
"*.for", | |||||
"*.f", | |||||
"*.f90", | |||||
"*.h", | |||||
"*.hh", | |||||
"*.hxx", | |||||
"*.hpp", | |||||
"*.h++", | |||||
"*.idl", | |||||
"*.ii", | |||||
"*.ixx", | |||||
"*.ipp", | |||||
"*.i++", | |||||
"*.inc", | |||||
"*.inl", | |||||
"*.java", | |||||
"*.js", | |||||
"*.m", | |||||
"*.md", | |||||
"*.mm", | |||||
"*.markdown", | |||||
"*.odl", | |||||
"*.php", | |||||
"*.php3", | |||||
"*.php4", | |||||
"*.php5", | |||||
"*.phtml", | |||||
"*.py", | |||||
"*.pyw", | |||||
"*.qsf", | |||||
"*.tcl", | |||||
"*.ucf" | |||||
], | |||||
"input-recursive": true, | |||||
"input-source": [ | |||||
"include/utl" | |||||
], | |||||
"mdfile-mainpage": "" | |||||
}, | |||||
"messages": { | |||||
"quiet": false, | |||||
"warn-doc-error": true, | |||||
"warn-format": "$file:$line: $text", | |||||
"warn-logfile": "", | |||||
"warn-undoc": true, | |||||
"warn-undoc-param": false, | |||||
"warnings": true | |||||
}, | |||||
"output-chm": { | |||||
"binary-toc": false, | |||||
"chm-file": "", | |||||
"chm-index-encoding": "", | |||||
"generate-chi": false, | |||||
"generate-chm": true, | |||||
"hhc-location": "", | |||||
"toc-expanded": false | |||||
}, | |||||
"output-docbook": { | |||||
"docbook-output": "docbook", | |||||
"docbook-program-listing": false, | |||||
"generate-docbook": false | |||||
}, | |||||
"output-docset": { | |||||
"docset-bundle-id": "org.doxypress.Project", | |||||
"docset-feedname": "DoxyPress generated docs", | |||||
"docset-publisher-id": "org.doxypress.Publisher", | |||||
"docset-publisher-name": "Publisher", | |||||
"generate-docset": false | |||||
}, | |||||
"output-eclipse": { | |||||
"eclipse-doc-id": "org.doxypress.Project", | |||||
"generate-eclipse": false | |||||
}, | |||||
"output-html": { | |||||
"disable-index": false, | |||||
"enum-values-per-line": 4, | |||||
"external-links-in-window": false, | |||||
"formula-fontsize": 10, | |||||
"formula-transparent": true, | |||||
"generate-html": true, | |||||
"generate-treeview": false, | |||||
"ghostscript": "", | |||||
"html-colorstyle-gamma": 80, | |||||
"html-colorstyle-hue": 220, | |||||
"html-colorstyle-sat": 100, | |||||
"html-dynamic-sections": false, | |||||
"html-extra-files": [ | |||||
"" | |||||
], | |||||
"html-file-extension": ".html", | |||||
"html-footer": "", | |||||
"html-header": "", | |||||
"html-index-num-entries": 100, | |||||
"html-output": "html", | |||||
"html-search": false, | |||||
"html-stylesheets": [ | |||||
"" | |||||
], | |||||
"html-timestamp": true, | |||||
"mathjax-codefile": "", | |||||
"mathjax-extensions": [ | |||||
"" | |||||
], | |||||
"mathjax-format": "HTML-CSS", | |||||
"mathjax-relpath": "https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.2/", | |||||
"search-data-file": "searchdata.xml", | |||||
"search-external": false, | |||||
"search-external-id": "", | |||||
"search-external-url": "", | |||||
"search-mappings": [ | |||||
"" | |||||
], | |||||
"search-server-based": false, | |||||
"treeview-width": 250, | |||||
"use-mathjax": false | |||||
}, | |||||
"output-latex": { | |||||
"cite-bib-files": [ | |||||
"" | |||||
], | |||||
"generate-latex": false, | |||||
"latex-batch-mode": false, | |||||
"latex-bib-style": "plain", | |||||
"latex-cmd-name": "latex", | |||||
"latex-compact": false, | |||||
"latex-extra-files": [ | |||||
"" | |||||
], | |||||
"latex-extra-packages": [ | |||||
"" | |||||
], | |||||
"latex-footer": "", | |||||
"latex-header": "", | |||||
"latex-hide-indices": false, | |||||
"latex-hyper-pdf": true, | |||||
"latex-output": "latex", | |||||
"latex-paper-type": "a4", | |||||
"latex-pdf": true, | |||||
"latex-ps": true, | |||||
"latex-source-code": false, | |||||
"latex-stylesheets": [ | |||||
"" | |||||
], | |||||
"latex-timestamp": false, | |||||
"make-index-cmd-name": "makeindex" | |||||
}, | |||||
"output-man": { | |||||
"generate-man": false, | |||||
"man-extension": ".3", | |||||
"man-links": false, | |||||
"man-output": "man", | |||||
"man-subdir": "" | |||||
}, | |||||
"output-perl": { | |||||
"generate-perl": false, | |||||
"perl-latex": false, | |||||
"perl-prefix": "", | |||||
"perl-pretty": true | |||||
}, | |||||
"output-qhelp": { | |||||
"generate-qthelp": false, | |||||
"qch-file": "", | |||||
"qhp-cust-attrib": [ | |||||
"" | |||||
], | |||||
"qhp-cust-filter-name": "", | |||||
"qhp-namespace": "org.doxypress.Project", | |||||
"qhp-sect-attrib": [ | |||||
"" | |||||
], | |||||
"qhp-virtual-folder": "doc", | |||||
"qthelp-gen-path": "" | |||||
}, | |||||
"output-rtf": { | |||||
"generate-rtf": false, | |||||
"rtf-compact": false, | |||||
"rtf-extension": "", | |||||
"rtf-hyperlinks": false, | |||||
"rtf-output": "rtf", | |||||
"rtf-paper-type": "a4", | |||||
"rtf-source-code": false, | |||||
"rtf-stylesheet": "" | |||||
}, | |||||
"output-xml": { | |||||
"generate-xml": false, | |||||
"xml-output": "xml", | |||||
"xml-program-listing": true | |||||
}, | |||||
"preprocessor": { | |||||
"enable-preprocessing": false, | |||||
"expand-as-defined": [ | |||||
"" | |||||
], | |||||
"expand-only-predefined": false, | |||||
"include-path": [ | |||||
"" | |||||
], | |||||
"include-patterns": [ | |||||
"" | |||||
], | |||||
"macro-expansion": false, | |||||
"predefined-macros": [ | |||||
"" | |||||
], | |||||
"search-includes": true, | |||||
"skip-function-macros": true | |||||
}, | |||||
"project": { | |||||
"project-brief": "micro Template Library", | |||||
"project-logo": "", | |||||
"project-name": "uTL", | |||||
"project-version": "" | |||||
}, | |||||
"source": { | |||||
"inline-source": true, | |||||
"ref-by-relation": false, | |||||
"ref-link-source": true, | |||||
"ref-relation": false, | |||||
"source-code": true, | |||||
"source-tooltips": true, | |||||
"strip-code-comments": true, | |||||
"suffix-exclude-navtree": [ | |||||
"doc", | |||||
"dox", | |||||
"md", | |||||
"markdown", | |||||
"txt" | |||||
], | |||||
"suffix-header-navtree": [ | |||||
"h", | |||||
"hh", | |||||
"hxx", | |||||
"hpp", | |||||
"h++", | |||||
"idl", | |||||
"ddl", | |||||
"pidl" | |||||
], | |||||
"suffix-source-navtree": [ | |||||
"c", | |||||
"cc", | |||||
"cxx", | |||||
"cpp", | |||||
"c++", | |||||
"ii", | |||||
"ixx", | |||||
"ipp", | |||||
"i++", | |||||
"inl", | |||||
"java", | |||||
"m", | |||||
"mm", | |||||
"xml" | |||||
], | |||||
"use-htags": false, | |||||
"verbatim-headers": true | |||||
} | |||||
} |
@@ -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,20 +1,6 @@ | |||||
/*! | /*! | ||||
* \file utl/impl/crtp.h | * \file utl/impl/crtp.h | ||||
* \brief CRTP idiom support header | * \brief CRTP idiom support header | ||||
* | |||||
* \copyright | |||||
* Copyright (C) 2018 Christos Choutouridis <christos@choutouridis.net>\n | |||||
* 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.\n | |||||
* 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.\n | |||||
* 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__ | ||||
@@ -1,20 +1,6 @@ | |||||
/*! | /*! | ||||
* \file utl/core/impl.h | * \file utl/core/impl.h | ||||
* \brief Implementation detail main forward header | * \brief Implementation detail main forward header | ||||
* | |||||
* \copyright | |||||
* Copyright (C) 2018 Christos Choutouridis <christos@choutouridis.net>\n | |||||
* 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.\n | |||||
* 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.\n | |||||
* 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__ | ||||
@@ -1,19 +1,6 @@ | |||||
/*! | /*! | ||||
* \file utl/core/types.h | * \file utl/core/types.h | ||||
* \brief Basic type alias support | * \brief Basic type alias support | ||||
* | |||||
* \copyright | |||||
* Copyright (C) 2018 Christos Choutouridis <christos@choutouridis.net>\n | |||||
* 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.\n | |||||
* 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.\n | |||||
* 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__ | ||||
@@ -1,20 +1,6 @@ | |||||
/*! | /*! | ||||
* \file utl/core/version.h | * \file utl/core/version.h | ||||
* \brief utl version and cpp version checks | * \brief utl version and cpp version checks | ||||
* | |||||
* \copyright | |||||
* Copyright (C) 2018 Christos Choutouridis <christos@choutouridis.net>\n | |||||
* 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.\n | |||||
* 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.\n | |||||
* 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_version_h__ | #ifndef __utl_core_version_h__ | ||||
#define __utl_core_version_h__ | #define __utl_core_version_h__ | ||||
@@ -1,20 +1,6 @@ | |||||
/*! | /*! | ||||
* \file utl/meta/basic.h | * \file utl/meta/basic.h | ||||
* \brief Template meta-programming basic definitions | * \brief Template meta-programming basic definitions | ||||
* | |||||
* \copyright | |||||
* Copyright (C) 2018 Christos Choutouridis <christos@choutouridis.net>\n | |||||
* 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.\n | |||||
* 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.\n | |||||
* 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_basic_h__ | #ifndef __utl_meta_basic_h__ | ||||
#define __utl_meta_basic_h__ | #define __utl_meta_basic_h__ | ||||
@@ -30,6 +16,13 @@ | |||||
*/ | */ | ||||
//! @{ | //! @{ | ||||
/*! | |||||
* \ingroup basic | |||||
* \defgroup meta_core Core | |||||
* Core definitions | |||||
*/ | |||||
//! @{ | |||||
namespace utl { | namespace utl { | ||||
namespace meta { | namespace meta { | ||||
@@ -44,19 +37,21 @@ namespace meta { | |||||
using type = nil_; | using type = nil_; | ||||
}; | }; | ||||
//! Type alias for \c Tp::type. Used to evaluate/extract return type of metafunctions | |||||
//! Type alias for \c Tp::type. | |||||
//! Is used to evaluate/extract return type of metafunctions | |||||
//! \tparam Tp The metafunction to evaluate | //! \tparam Tp The metafunction to evaluate | ||||
//! \return The inner \::type | //! \return The inner \::type | ||||
template <typename Tp> | template <typename Tp> | ||||
using eval = typename Tp::type; | using eval = typename Tp::type; | ||||
//! Type alias for \c Tp::type. Used to evaluate/extract return type of metafunctions | |||||
//! 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> | template <typename Tp> | ||||
using eval_t = typename Tp::type; | |||||
using eval_v = typename eval<Tp>::value; | |||||
//! Type alias for \c Tp::value. Used to evaluate/extract return value of metafunctions | |||||
template <typename Tp> | |||||
using eval_v = typename Tp::value; | |||||
//! | //! | ||||
//! integral_ is a holder class for a compile-time value of an integral type. | //! integral_ is a holder class for a compile-time value of an integral type. | ||||
@@ -119,6 +114,13 @@ namespace meta { | |||||
template<size_t v> | template<size_t v> | ||||
using size_ = integral_<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. | //! Computes the size of the type \p Tp. | ||||
//! Complexity \f$ O(1) \f$. | //! Complexity \f$ O(1) \f$. | ||||
template <typename Tp> | template <typename Tp> | ||||
@@ -130,9 +132,6 @@ namespace meta { | |||||
using alignof_ = size_<alignof(Tp)>; | using alignof_ = size_<alignof(Tp)>; | ||||
//! @} | //! @} | ||||
//! The last position we can express for indexing | |||||
using Npos = size_<index_t(-1)>; | |||||
//! \name integer sequence | //! \name integer sequence | ||||
//! @{ | //! @{ | ||||
template< class Tp, Tp... Ints > | template< class Tp, Tp... Ints > | ||||
@@ -152,10 +151,265 @@ namespace meta { | |||||
//! Alias template index_sequence_for | //! Alias template index_sequence_for | ||||
template<typename... Types> | template<typename... Types> | ||||
using index_sequence_for = make_index_sequence<sizeof...(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__ */ | #endif /* __utl_meta_basic_h__ */ |
@@ -1,32 +1,17 @@ | |||||
/*! | /*! | ||||
* \file detection.h | * \file detection.h | ||||
* \brief Detection idiom based on WG21's \ref N4502 from Walter E. Brown | |||||
* | |||||
* \copyright | |||||
* Copyright (C) 2018 Christos Choutouridis <christos@choutouridis.net>\n | |||||
* 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.\n | |||||
* 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.\n | |||||
* 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 N4502 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. | ||||
*/ | */ | ||||
//! @{ | //! @{ | ||||
@@ -45,7 +30,7 @@ namespace meta { | |||||
}; | }; | ||||
//! void_t type alias | //! void_t type alias | ||||
template<typename... _Ts> | template<typename... _Ts> | ||||
using void_t = eval_t<void_<_Ts...>>; | |||||
using void_t = eval<void_<_Ts...>>; | |||||
#else | #else | ||||
//! void_ meta-function that maps a sequence of any types to the type void | //! void_ meta-function that maps a sequence of any types to the type void | ||||
template <typename...> using void_ = void; | template <typename...> using void_ = void; | ||||
@@ -138,7 +123,7 @@ namespace meta { | |||||
* \endcode | * \endcode | ||||
*/ | */ | ||||
template <template<typename...> class Op, typename... Args> | template <template<typename...> class Op, typename... Args> | ||||
using detected_t = eval_t < | |||||
using detected_t = eval < | |||||
details::detector<nat_, void, Op, Args...> | details::detector<nat_, void, Op, Args...> | ||||
>; | >; | ||||
@@ -164,7 +149,7 @@ 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_t < | |||||
using detected_or_t = eval < | |||||
details::detected_or<Default, Op, Args...> | details::detected_or<Default, Op, Args...> | ||||
>; | >; | ||||
@@ -191,7 +176,7 @@ namespace meta { | |||||
*/ | */ | ||||
template <typename Expected, | template <typename Expected, | ||||
template<typename...> class Op, typename... Args > | template<typename...> class Op, typename... Args > | ||||
using is_detected_exact = eval_t < | |||||
using is_detected_exact = eval < | |||||
same_<Expected, detected_t<Op, Args...>> | same_<Expected, detected_t<Op, Args...>> | ||||
>; | >; | ||||
@@ -223,7 +208,7 @@ namespace meta { | |||||
*/ | */ | ||||
template <typename To, | template <typename To, | ||||
template<typename...> class Op, typename... Args > | template<typename...> class Op, typename... Args > | ||||
using is_detected_convertible = eval_t < | |||||
using is_detected_convertible = eval < | |||||
std::is_convertible< detected_t<Op, Args...>, To > | std::is_convertible< detected_t<Op, Args...>, To > | ||||
>; | >; | ||||
@@ -1,19 +1,6 @@ | |||||
/*! | /*! | ||||
* \file utl/meta/invoke.h | * \file utl/meta/invoke.h | ||||
* \brief Template meta-programming utilities for callables | * \brief Template meta-programming utilities for callables | ||||
* | |||||
* \copyright | |||||
* Copyright (C) 2018 Christos Choutouridis <christos@choutouridis.net>\n | |||||
* 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.\n | |||||
* 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.\n | |||||
* 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__ | ||||
@@ -21,17 +8,26 @@ | |||||
#include <utl/core/impl.h> | #include <utl/core/impl.h> | ||||
#include <utl/meta/basic.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 | |||||
* 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. | |||||
* \defgroup 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: | |||||
* | * | ||||
* - 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. | |||||
* - 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 { | ||||
@@ -1,32 +1,39 @@ | |||||
/*! | /*! | ||||
* \file utl/meta/meta.h | * \file utl/meta/meta.h | ||||
* \brief Meta library forward header | * \brief Meta library forward header | ||||
* | |||||
* \copyright | |||||
* Copyright (C) 2018 Christos Choutouridis <christos@choutouridis.net>\n | |||||
* 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.\n | |||||
* 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.\n | |||||
* 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_meta_h__ | #ifndef __utl_meta_meta_h__ | ||||
#define __utl_meta_meta_h__ | #define __utl_meta_meta_h__ | ||||
//! \defgroup meta Meta | |||||
//! An embedded metaprogramming library for uTL. | |||||
//! | |||||
/*! \defgroup meta Meta | |||||
* An embedded metaprogramming library for uTL. | |||||
* | |||||
* 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 consist of: | |||||
* | |||||
* - 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... | |||||
* All of these operate on integral types. | |||||
* - <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 other metafunctions. The evaluation | |||||
* of these functions can be done both aggressive or lazy 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... | |||||
*/ | |||||
#include <utl/meta/basic.h> | #include <utl/meta/basic.h> | ||||
#include <utl/meta/selection.h> | |||||
#include <utl/meta/operations.h> | |||||
#include <utl/meta/useif.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,225 +0,0 @@ | |||||
/*! | |||||
* \file operations.h | |||||
* \brief Integral constant operations and logical operations | |||||
* | |||||
* \copyright | |||||
* Copyright (C) 2018 Christos Choutouridis <christos@choutouridis.net>\n | |||||
* 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.\n | |||||
* 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.\n | |||||
* 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_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_t<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_t<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_t<same_<T1, T2>>>; | |||||
//! @} | |||||
//! @} | |||||
}} | |||||
//! @} | |||||
/*! | |||||
* \ingroup meta | |||||
* \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::valueType, (typename T::valueType)(~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,79 +0,0 @@ | |||||
/*! | |||||
* \file selection.h | |||||
* \brief Template meta-programming type selections. | |||||
* | |||||
* \copyright | |||||
* Copyright (C) 2018 Christos Choutouridis <christos@choutouridis.net>\n | |||||
* 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.\n | |||||
* 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.\n | |||||
* 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/basic.h> | |||||
/*! | |||||
* \ingroup meta | |||||
* \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_t<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; | |||||
//! @} | |||||
}} | |||||
//! @} | |||||
#endif /* __utl_meta_selection_h__ */ |
@@ -1,19 +1,6 @@ | |||||
/*! | /*! | ||||
* \file sfinae.h | * \file sfinae.h | ||||
* \brief Template meta-programming SFINAE helpers | * \brief Template meta-programming SFINAE helpers | ||||
* | |||||
* \copyright | |||||
* Copyright (C) 2018 Christos Choutouridis <christos@choutouridis.net>\n | |||||
* 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.\n | |||||
* 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.\n | |||||
* 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__ | ||||
@@ -23,13 +10,24 @@ | |||||
/*! | /*! | ||||
* \ingroup meta | * \ingroup meta | ||||
* \defgroup sfinae sfinae | |||||
* \defgroup sfinae SFINAE | |||||
* conditional use support header. | * conditional use support header. | ||||
*/ | */ | ||||
//! @{ | //! @{ | ||||
namespace utl { | namespace utl { | ||||
namespace meta { | namespace meta { | ||||
//! \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 | //! \name when implementation | ||||
//! @{ | //! @{ | ||||
namespace details { | namespace details { | ||||
@@ -42,7 +40,7 @@ namespace meta { | |||||
//! Tool to enable a partial specialization only if a boolean condition is true. | //! 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_t< details::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> | ||||
@@ -52,16 +50,29 @@ namespace meta { | |||||
//! @} | //! @} | ||||
//! \name enable_if from STL | |||||
//! @{ | |||||
//! 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_t< enable_if<If, _Tp> >; | |||||
//! @} | |||||
}} | }} | ||||
@@ -32,7 +32,7 @@ namespace meta { | |||||
* (even if the parameter typelist contains void or some type that lacks | * (even if the parameter typelist contains void or some type that lacks | ||||
* a default constructor).\n | * a default constructor).\n | ||||
* | * | ||||
* \code | |||||
* \code{.cpp} | |||||
* using l1 = typelist<int, void*, double, void>; | * using l1 = typelist<int, void*, double, void>; | ||||
* l1 a {}; | * l1 a {}; | ||||
* \endcode | * \endcode | ||||
@@ -89,7 +89,7 @@ namespace meta { | |||||
/*! | /*! | ||||
* Generate typelist<Ts..., Ts..., ...> of size \c N arguments. | * Generate typelist<Ts..., Ts..., ...> of size \c N arguments. | ||||
* | * | ||||
* \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> | ||||
@@ -108,8 +108,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()>; | ||||
@@ -119,8 +119,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()>; | ||||
@@ -131,24 +131,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. | ||||
*/ | */ | ||||
@@ -157,7 +157,7 @@ namespace meta { | |||||
template <typename Fn, typename Seq> | template <typename Fn, typename Seq> | ||||
struct apply_ { }; | struct apply_ { }; | ||||
//! \p Sequence == typelist<> | |||||
//! \c 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...>; | ||||
@@ -170,13 +170,13 @@ namespace meta { | |||||
} | } | ||||
/*! | /*! | ||||
* Apply the Invocable \p Fn using the types in the type \p Seq as arguments. | |||||
* 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 | |||||
* If \c Seq == typelist<> then | |||||
* Unpack typelist and apply to \c Fn | * Unpack typelist and apply to \c Fn | ||||
* It \p Seq == integer_sequence<> then | |||||
* It \c Seq == integer_sequence<> then | |||||
* Unpack and use the integral_c<> of each integer | * Unpack and use the integral_c<> of each integer | ||||
*/ | */ | ||||
template <typename Fn, typename Seq> | template <typename Fn, typename Seq> | ||||
@@ -190,9 +190,9 @@ namespace meta { | |||||
/* | /* | ||||
* ========= element access ======== | * ========= element access ======== | ||||
*/ | */ | ||||
//! at: random element access | |||||
//! \name random element access | |||||
//! @{ | //! @{ | ||||
namespace details { | |||||
namespace at_impl { | |||||
template <typename T> struct _add_pointer { using type = T*; }; | template <typename T> struct _add_pointer { using type = T*; }; | ||||
template <typename T> using add_pointer = eval < _add_pointer <T> >; | template <typename T> using add_pointer = eval < _add_pointer <T> >; | ||||
@@ -221,26 +221,26 @@ 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$. | ||||
*/ | */ | ||||
template <typename List, index_t N> | template <typename List, index_t N> | ||||
using at_c = eval< | using at_c = eval< | ||||
details::at_<List, N> | |||||
at_impl::at_<List, N> | |||||
>; | >; | ||||
/*! | /*! | ||||
* 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> | ||||
@@ -252,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< | ||||
@@ -260,7 +261,7 @@ namespace meta { | |||||
>; | >; | ||||
//! @} | //! @} | ||||
//! back | |||||
//! \name back | |||||
//! @{ | //! @{ | ||||
namespace back_impl { | namespace back_impl { | ||||
template <typename List> | template <typename List> | ||||
@@ -274,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< | ||||
@@ -285,7 +287,7 @@ namespace meta { | |||||
* ========= typelist operations ========= | * ========= typelist operations ========= | ||||
*/ | */ | ||||
//! Concatenation | |||||
//! \name Concatenation | |||||
//! @{ | //! @{ | ||||
namespace cat_impl { | namespace cat_impl { | ||||
template <typename... Lists> | template <typename... Lists> | ||||
@@ -315,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< | ||||
@@ -325,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> | ||||
@@ -354,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>>; | ||||
@@ -407,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< | ||||
@@ -425,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> | ||||
@@ -436,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> | ||||
@@ -446,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<>> | ||||
@@ -456,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> | ||||
@@ -465,7 +473,7 @@ namespace meta { | |||||
>; | >; | ||||
//! @} | //! @} | ||||
//! pop_front | |||||
//! \name pop_front | |||||
//! @{ | //! @{ | ||||
namespace pop_front_impl { | namespace pop_front_impl { | ||||
template <typename List> | template <typename List> | ||||
@@ -479,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> | ||||
@@ -488,7 +497,7 @@ namespace meta { | |||||
>; | >; | ||||
//! @} | //! @} | ||||
//! pop_back | |||||
//! \name pop_back | |||||
//! @{ | //! @{ | ||||
namespace pop_back_impl { | namespace pop_back_impl { | ||||
template <typename List> | template <typename List> | ||||
@@ -500,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 | ||||
@@ -512,7 +522,7 @@ namespace meta { | |||||
>; | >; | ||||
//! @} | //! @} | ||||
//! Transform | |||||
//! \name Transform | |||||
//! @{ | //! @{ | ||||
namespace transform_impl { | namespace transform_impl { | ||||
template <typename, typename = void> | template <typename, typename = void> | ||||
@@ -540,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 | ||||
@@ -554,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> | ||||
@@ -586,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 | ||||
@@ -601,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> | ||||
@@ -627,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. | ||||
*/ | */ | ||||
@@ -643,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> | ||||
@@ -675,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> | ||||
@@ -690,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> | ||||
@@ -726,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> | ||||
@@ -741,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> | ||||
@@ -772,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< | ||||
@@ -786,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> | ||||
@@ -811,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> | ||||
@@ -826,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> | ||||
@@ -835,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>, | ||||
@@ -846,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,60 +0,0 @@ | |||||
/*! | |||||
* \file useif.h | |||||
* \brief Template meta-programming SFINAE helpers | |||||
* | |||||
* \copyright | |||||
* Copyright (C) 2018 Christos Choutouridis <christos@choutouridis.net>\n | |||||
* 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.\n | |||||
* 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.\n | |||||
* 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 | |||||
* \addtogroup sfinae | |||||
*/ | |||||
//! @{ | |||||
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< | |||||
eval_v<same_<T1, T2>>, 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< | |||||
eval_v<not_same_<T1, T2>>, 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< | |||||
eval_v<or_<T1, Ts...>>, 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< | |||||
eval_v<and_<T1, Ts...>>, 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__ | ||||
@@ -29,7 +14,7 @@ | |||||
/*! | /*! | ||||
* \ingroup utility | * \ingroup utility | ||||
* \defgroup invoke | |||||
* \defgroup invoke Invoke | |||||
*/ | */ | ||||
//! @{ | //! @{ | ||||
namespace utl { | namespace utl { | ||||
@@ -125,7 +110,7 @@ namespace utl { | |||||
} | } | ||||
//! @} | //! @} | ||||
//! std::is_invocable trait for C++11 | |||||
//! std::is_invocable trait for C++14 | |||||
template <typename F, typename... Args> | template <typename F, typename... Args> | ||||
struct is_invocable : | struct is_invocable : | ||||
std::is_constructible< | std::is_constructible< | ||||
@@ -133,7 +118,7 @@ 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 | |||||
//! std::is_invocable_r trait for C++14 | |||||
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< | ||||