Selaa lähdekoodia

WIP: documentation setup

doc
Christos Choutouridis 4 vuotta sitten
vanhempi
commit
c7050f28bf
17 muutettua tiedostoa jossa 464 lisäystä ja 1139 poistoa
  1. +1
    -1
      Doxyfile
  2. +0
    -486
      Doxypress
  3. +0
    -16
      include/utl/concepts/stl.h
  4. +0
    -14
      include/utl/core/crtp.h
  5. +0
    -14
      include/utl/core/impl.h
  6. +0
    -13
      include/utl/core/types.h
  7. +0
    -14
      include/utl/core/version.h
  8. +278
    -24
      include/utl/meta/basic.h
  9. +8
    -23
      include/utl/meta/detection.h
  10. +16
    -20
      include/utl/meta/invoke.h
  11. +27
    -20
      include/utl/meta/meta.h
  12. +0
    -225
      include/utl/meta/operations.h
  13. +0
    -79
      include/utl/meta/selection.h
  14. +33
    -22
      include/utl/meta/sfinae.h
  15. +98
    -90
      include/utl/meta/typelist.h
  16. +0
    -60
      include/utl/meta/useif.h
  17. +3
    -18
      include/utl/utility/invoke.h

+ 1
- 1
Doxyfile Näytä tiedosto

@@ -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


+ 0
- 486
Doxypress Näytä tiedosto

@@ -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
}
}

+ 0
- 16
include/utl/concepts/stl.h Näytä tiedosto

@@ -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__


+ 0
- 14
include/utl/core/crtp.h Näytä tiedosto

@@ -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__


+ 0
- 14
include/utl/core/impl.h Näytä tiedosto

@@ -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__


+ 0
- 13
include/utl/core/types.h Näytä tiedosto

@@ -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__


+ 0
- 14
include/utl/core/version.h Näytä tiedosto

@@ -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__


+ 278
- 24
include/utl/meta/basic.h Näytä tiedosto

@@ -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__ */

+ 8
- 23
include/utl/meta/detection.h Näytä tiedosto

@@ -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 >
>;


+ 16
- 20
include/utl/meta/invoke.h Näytä tiedosto

@@ -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 {


+ 27
- 20
include/utl/meta/meta.h Näytä tiedosto

@@ -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>


+ 0
- 225
include/utl/meta/operations.h Näytä tiedosto

@@ -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__ */

+ 0
- 79
include/utl/meta/selection.h Näytä tiedosto

@@ -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__ */

+ 33
- 22
include/utl/meta/sfinae.h Näytä tiedosto

@@ -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> >;
//! @}
}}


+ 98
- 90
include/utl/meta/typelist.h Näytä tiedosto

@@ -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>


+ 0
- 60
include/utl/meta/useif.h Näytä tiedosto

@@ -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__ */

+ 3
- 18
include/utl/utility/invoke.h Näytä tiedosto

@@ -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<


Loading…
Peruuta
Tallenna