@@ -1087,7 +1087,7 @@ CLANG_ASSISTED_PARSING = YES | |||
# specified with INPUT and INCLUDE_PATH. | |||
# 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 | |||
@@ -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 | |||
* \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__ | |||
#define __utl_concepts_stl_h__ | |||
@@ -1,20 +1,6 @@ | |||
/*! | |||
* \file utl/impl/crtp.h | |||
* \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__ | |||
#define __utl_impl_crtp_h__ | |||
@@ -1,20 +1,6 @@ | |||
/*! | |||
* \file utl/core/impl.h | |||
* \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__ | |||
#define __utl_core_impl_h__ | |||
@@ -1,19 +1,6 @@ | |||
/*! | |||
* \file utl/core/types.h | |||
* \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__ | |||
@@ -1,20 +1,6 @@ | |||
/*! | |||
* \file utl/core/version.h | |||
* \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__ | |||
#define __utl_core_version_h__ | |||
@@ -1,20 +1,6 @@ | |||
/*! | |||
* \file utl/meta/basic.h | |||
* \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__ | |||
#define __utl_meta_basic_h__ | |||
@@ -30,6 +16,13 @@ | |||
*/ | |||
//! @{ | |||
/*! | |||
* \ingroup basic | |||
* \defgroup meta_core Core | |||
* Core definitions | |||
*/ | |||
//! @{ | |||
namespace utl { | |||
namespace meta { | |||
@@ -44,19 +37,21 @@ namespace meta { | |||
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 | |||
//! \return The inner \::type | |||
template <typename Tp> | |||
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> | |||
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. | |||
@@ -119,6 +114,13 @@ namespace meta { | |||
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> | |||
@@ -130,9 +132,6 @@ namespace meta { | |||
using alignof_ = size_<alignof(Tp)>; | |||
//! @} | |||
//! The last position we can express for indexing | |||
using Npos = size_<index_t(-1)>; | |||
//! \name integer sequence | |||
//! @{ | |||
template< class Tp, Tp... Ints > | |||
@@ -152,10 +151,265 @@ namespace meta { | |||
//! 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,32 +1,17 @@ | |||
/*! | |||
* \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__ | |||
#define __utl_meta_detection_h__ | |||
#include <utl/core/impl.h> | |||
#include <utl/meta/operations.h> | |||
#include <utl/meta/basic.h> | |||
#include <type_traits> | |||
/*! | |||
* \ingroup meta | |||
* \defgroup detection | |||
* \defgroup detection Detection | |||
* Detection idiom support header. | |||
*/ | |||
//! @{ | |||
@@ -45,7 +30,7 @@ namespace meta { | |||
}; | |||
//! void_t type alias | |||
template<typename... _Ts> | |||
using void_t = eval_t<void_<_Ts...>>; | |||
using void_t = eval<void_<_Ts...>>; | |||
#else | |||
//! void_ meta-function that maps a sequence of any types to the type void | |||
template <typename...> using void_ = void; | |||
@@ -138,7 +123,7 @@ namespace meta { | |||
* \endcode | |||
*/ | |||
template <template<typename...> class Op, typename... Args> | |||
using detected_t = eval_t < | |||
using detected_t = eval < | |||
details::detector<nat_, void, Op, Args...> | |||
>; | |||
@@ -164,7 +149,7 @@ namespace meta { | |||
*/ | |||
template <typename Default, | |||
template<typename...> class Op, typename... Args> | |||
using detected_or_t = eval_t < | |||
using detected_or_t = eval < | |||
details::detected_or<Default, Op, Args...> | |||
>; | |||
@@ -191,7 +176,7 @@ namespace meta { | |||
*/ | |||
template <typename Expected, | |||
template<typename...> class Op, typename... Args > | |||
using is_detected_exact = eval_t < | |||
using is_detected_exact = eval < | |||
same_<Expected, detected_t<Op, Args...>> | |||
>; | |||
@@ -223,7 +208,7 @@ namespace meta { | |||
*/ | |||
template <typename To, | |||
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 > | |||
>; | |||
@@ -1,19 +1,6 @@ | |||
/*! | |||
* \file utl/meta/invoke.h | |||
* \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__ | |||
#define __utl_meta_invoke_h__ | |||
@@ -21,17 +8,26 @@ | |||
#include <utl/core/impl.h> | |||
#include <utl/meta/basic.h> | |||
#include <utl/meta/detection.h> | |||
#include <utl/meta/operations.h> | |||
/*! | |||
* \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 { | |||
@@ -1,32 +1,39 @@ | |||
/*! | |||
* \file utl/meta/meta.h | |||
* \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__ | |||
#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/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/detection.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 | |||
* \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__ | |||
#define __utl_meta_sfinae_h__ | |||
@@ -23,13 +10,24 @@ | |||
/*! | |||
* \ingroup meta | |||
* \defgroup sfinae sfinae | |||
* \defgroup sfinae SFINAE | |||
* conditional use support header. | |||
*/ | |||
//! @{ | |||
namespace utl { | |||
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 | |||
//! @{ | |||
namespace details { | |||
@@ -42,7 +40,7 @@ namespace meta { | |||
//! Tool to enable a partial specialization only if a boolean condition is true. | |||
//! Well formed only if \p If is true | |||
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 | |||
// 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 | |||
* a default constructor).\n | |||
* | |||
* \code | |||
* \code{.cpp} | |||
* using l1 = typelist<int, void*, double, void>; | |||
* l1 a {}; | |||
* \endcode | |||
@@ -89,7 +89,7 @@ namespace meta { | |||
/*! | |||
* Generate typelist<Ts..., Ts..., ...> of size \c N arguments. | |||
* | |||
* \code | |||
* \code{.cpp} | |||
* static_assert ( | |||
* std::is_same<typelist<int, char>::times<2>, | |||
* typelist<int, char, int, char> | |||
@@ -108,8 +108,8 @@ namespace meta { | |||
* | |||
* 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> | |||
using size = size_<List::size()>; | |||
@@ -119,8 +119,8 @@ namespace meta { | |||
* | |||
* Complexity \f$ O(1) \f$. | |||
* | |||
* \param List A typelist | |||
* \return Empty or not | |||
* \tparam List A typelist | |||
* \return Empty or not | |||
*/ | |||
template <typename List> | |||
using empty = bool_<List::empty()>; | |||
@@ -131,24 +131,24 @@ namespace meta { | |||
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> | |||
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> | |||
using repeat = repeat_c<N::type::value, Ts...>; | |||
//! @} | |||
/*! | |||
* Apply | |||
* \name Apply | |||
* An analogous to apply() implementation for tuples. We just use | |||
* Our typelist<> and integer_sequence<> types. | |||
*/ | |||
@@ -157,7 +157,7 @@ namespace meta { | |||
template <typename Fn, typename Seq> | |||
struct apply_ { }; | |||
//! \p Sequence == typelist<> | |||
//! \c Sequence == typelist<> | |||
template<typename Fn, typename ...List> | |||
struct apply_<Fn, typelist<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 | |||
* 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 | |||
* It \p Seq == integer_sequence<> then | |||
* It \c Seq == integer_sequence<> then | |||
* Unpack and use the integral_c<> of each integer | |||
*/ | |||
template <typename Fn, typename Seq> | |||
@@ -190,9 +190,9 @@ namespace meta { | |||
/* | |||
* ========= 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> 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$. | |||
*/ | |||
template <typename List, index_t N> | |||
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> | |||
using at = at_c<List, N::type::value>; | |||
//!@} | |||
//! front | |||
//! \name front | |||
//! @{ | |||
namespace front_impl { | |||
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$. | |||
template <typename List> | |||
using front = eval< | |||
@@ -260,7 +261,7 @@ namespace meta { | |||
>; | |||
//! @} | |||
//! back | |||
//! \name back | |||
//! @{ | |||
namespace back_impl { | |||
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$. | |||
template <typename List> | |||
using back = eval< | |||
@@ -285,7 +287,7 @@ namespace meta { | |||
* ========= typelist operations ========= | |||
*/ | |||
//! Concatenation | |||
//! \name Concatenation | |||
//! @{ | |||
namespace cat_impl { | |||
template <typename... Lists> | |||
@@ -315,8 +317,9 @@ namespace meta { | |||
/*! | |||
* Transformation that concatenates several lists into a single typelist. | |||
* The parameters must all be instantiations of \c meta::typelist. | |||
* | |||
* 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> | |||
using cat = eval< | |||
@@ -325,7 +328,7 @@ namespace meta { | |||
//! @} | |||
//! fold<List, V, Fn>, rev_fold<List, V, Fn> | |||
//! \name Fold | |||
//! @{ | |||
namespace fold_impl { | |||
// 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$ | |||
* \example | |||
* \code{.cpp} | |||
* fold<typelist<T1, T2, T3>, V, F> == F<F<F<V, T1>, T2>, T3> | |||
* \example | |||
* 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> | |||
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$ | |||
* \example | |||
* \code{.cpp} | |||
* rev_fold<typelist<T1, T2, T3>, V, F> == F<T1, F<T2, F<T3, V>>> | |||
* \example | |||
* 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> | |||
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$ | |||
*/ | |||
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$ | |||
*/ | |||
template <typename List, typename... Ts> | |||
@@ -446,7 +453,7 @@ namespace meta { | |||
> | |||
>; | |||
//! reverse | |||
//! \name reverse | |||
//! @{ | |||
namespace reverse_impl { | |||
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$ | |||
*/ | |||
template <typename List> | |||
@@ -465,7 +473,7 @@ namespace meta { | |||
>; | |||
//! @} | |||
//! pop_front | |||
//! \name pop_front | |||
//! @{ | |||
namespace pop_front_impl { | |||
template <typename List> | |||
@@ -479,7 +487,8 @@ namespace meta { | |||
/*! | |||
* 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$ | |||
*/ | |||
template <typename List> | |||
@@ -488,7 +497,7 @@ namespace meta { | |||
>; | |||
//! @} | |||
//! pop_back | |||
//! \name pop_back | |||
//! @{ | |||
namespace pop_back_impl { | |||
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$. | |||
* \note | |||
* This operation, in addition from other push/pop operations, is | |||
@@ -512,7 +522,7 @@ namespace meta { | |||
>; | |||
//! @} | |||
//! Transform | |||
//! \name Transform | |||
//! @{ | |||
namespace transform_impl { | |||
template <typename, typename = void> | |||
@@ -540,8 +550,7 @@ namespace meta { | |||
* and return the resulting typelist | |||
* | |||
* Complexity \f$ O(N) \f$. | |||
* \example | |||
* \code | |||
* \code{.cpp} | |||
* using l1 = typelist<char, int, ...>; | |||
* using l2 = typelist<void, double, ...>; | |||
* using r1 = transform<l1, F1>; // F1, unary invocable | |||
@@ -554,7 +563,7 @@ namespace meta { | |||
>; | |||
//! @} | |||
//! Transform lazy | |||
//! \name Transform lazy | |||
//! @{ | |||
namespace transform_lazy_impl { | |||
template <typename, typename = void> | |||
@@ -586,8 +595,7 @@ namespace meta { | |||
* | |||
* Complexity \f$ O(N) \f$ | |||
* | |||
* \example | |||
* \code | |||
* \code{.cpp} | |||
* using l1 = typelist<char, int, ...>; | |||
* using l2 = typelist<void, void, ...>; | |||
* 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 { | |||
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>>` | |||
* | |||
* 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, | |||
* 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> | |||
using find = find_if<List, same_as<T>>; | |||
//! @} | |||
//! seek_if | |||
//! \name seek_if | |||
//! @{ | |||
namespace seek_if_impl { | |||
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 | |||
* | |||
* 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 | |||
*/ | |||
template <typename List, typename Pred> | |||
@@ -690,14 +698,14 @@ namespace meta { | |||
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> | |||
using seek = seek_if <List, same_as<T>>; | |||
//! @} | |||
//! count_if | |||
//! \name count_if | |||
//! @{ | |||
namespace count_if_impl { | |||
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>>` | |||
* | |||
* 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 | |||
*/ | |||
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> | |||
using count = count_if<List, same_as<T>>; | |||
//! @} | |||
//! filter | |||
//! \name filter | |||
//! @{ | |||
namespace filter_impl { | |||
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$ | |||
* | |||
* \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> | |||
using filter = eval< | |||
@@ -786,7 +794,7 @@ namespace meta { | |||
>; | |||
//! @} | |||
//! replace | |||
//! \name replace | |||
//! @{ | |||
namespace replace_if_impl { | |||
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$ | |||
* | |||
* \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_ | |||
*/ | |||
template<typename List, typename Pred, typename T> | |||
@@ -826,8 +834,8 @@ namespace meta { | |||
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> | |||
using replace = eval < | |||
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> | |||
using all_of = if_ < | |||
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. | |||
template <typename List, typename Pred> | |||
using any_of = not_< | |||
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> | |||
using none_of = empty< | |||
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 | |||
* \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__ | |||
#define __utl_utility_invoke_h__ | |||
@@ -29,7 +14,7 @@ | |||
/*! | |||
* \ingroup utility | |||
* \defgroup invoke | |||
* \defgroup invoke Invoke | |||
*/ | |||
//! @{ | |||
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> | |||
struct is_invocable : | |||
std::is_constructible< | |||
@@ -133,7 +118,7 @@ namespace utl { | |||
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> | |||
struct is_invocable_r : | |||
std::is_constructible< | |||