diff --git a/.travis.yml b/.travis.yml
index f9c23d05..26f0c56d 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -83,7 +83,7 @@ install:
- |
if [[ "${BUILD_DOC}" == "true" ]]
then
- DOXYGEN_URL="http://ftp.stack.nl/pub/users/dimitri/doxygen-1.8.10.linux.bin.tar.gz"
+ DOXYGEN_URL="http://ftp.stack.nl/pub/users/dimitri/doxygen-1.8.11.linux.bin.tar.gz"
mkdir "${DEPS_PATH}/doxygen" &&
travis_retry wget --quiet -O - ${DOXYGEN_URL} | tar --strip-components=1 -xz -C "${DEPS_PATH}/doxygen" &&
export PATH=${DEPS_PATH}/doxygen/bin:${PATH}
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 45e03be8..ad64ea27 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -94,10 +94,6 @@ endif()
if(METAL_ENABLE_EXTRA_WARNINGS)
metal_add_flag(-Wextra)
- metal_add_flag(-Weverything)
- metal_add_flag(-Wno-c++98-compat)
- metal_add_flag(-Wno-c++98-compat-pedantic)
- metal_add_flag(-Wno-documentation-unknown-command)
metal_add_flag(/W4)
endif()
@@ -107,8 +103,6 @@ if(METAL_STRICT)
metal_add_flag(/WX)
endif()
-metal_add_flag(-ftemplate-depth=512)
-
foreach(dialect
-std=c++17 -std=c++1z
-std=c++14 -std=c++1y
diff --git a/doc/Doxyfile.in b/doc/Doxyfile.in
index d4a3682a..5d4a6602 100644
--- a/doc/Doxyfile.in
+++ b/doc/Doxyfile.in
@@ -228,6 +228,8 @@ TAB_SIZE = 4
# "Side Effects:". You can put \n's in the value part of an alias to insert
# newlines.
+ALIASES += strike{1}="
\1
"
+
ALIASES +=value="\ref concepts_value"
ALIASES +=values="\ref concepts_value \"Values\""
ALIASES +=optional="\ref concepts_optional"
diff --git a/doc/css/metal.css b/doc/css/metal.css
index 7916ddeb..14b35637 100644
--- a/doc/css/metal.css
+++ b/doc/css/metal.css
@@ -129,6 +129,10 @@ span.octicon {
margin-right: 5px;
}
+.strike {
+ text-decoration: line-through;
+}
+
#footer {
height: 100px;
font-size: 0.9em;
diff --git a/doc/manual.md b/doc/manual.md
index de7a992c..04e8d05f 100644
--- a/doc/manual.md
+++ b/doc/manual.md
@@ -2,23 +2,11 @@
\tableofcontents
-Metal is a general-purpose, header-only [C++11][C++11]
-[template metaprogramming][tmp] library designed to make
-metaprogramming enjoyable.
-It provides a powerful high-level abstraction for compile-time algorithms,
-grounded on a concise yet solid [conceptual foundation](\ref concepts).
-
-With focus on [simplicity] and [expressiveness],
-Metal explores the full potential of modern features, without,
-on the other hand,
-allowing its [portability](\ref portability) to be compromised.
-Metal does its best to follow the
-[principle of least astonishment][pola],
-mimicking well established concepts used by the [STL], much like its ancestor
-and main source of inspiration, the [Boost.MPL].
-In fact, Metal was born *MPL2*, an independent attempt to modernize Boost.MPL,
-but soon it became clear that it was something more than just a remake,
-so thus became **Metal** - Metaprogramming Algorithms.
+Metal is a [portable](\ref portability) header-only [C++11] library
+designed to make [template metaprogramming][tmp] enjoyable.
+To that end, it provides a powerful high-level [abstraction](\ref concepts) for
+compile-time algorithms that mimic the [standard algorithms library][algorithm],
+hence **Metal** - Metaprogramming Algorithms.
Motivation {#motivation}
================================================================================
@@ -39,16 +27,16 @@ by Aleksey Gurtovoy and David Abrahams,
is officially shipped with Boost version 1.30.0.
A masterpiece of template metaprogramming,
it went to great lengths to support the
-widest variety of poorly conforming if not utterly defective compilers,
+widest variety of poorly conforming compilers,
abstracting away the nastiest compiler hackery to present a uniform
-framework that finally could be relied upon.
-It played a crucial role in the dissemination of metaprogramming in C++ and
-remained undisputed for almost a decade,
-but, eventually, it started showing its age when [C++11] introduced,
+framework that finally could be relied upon,
+thus playing a crucial role in the dissemination of metaprogramming in C++.
+The Boost.MPL remained undisputed for almost a decade, but
+eventually, it started showing its age when [C++11] introduced,
among various others,
[variadic templates][variadics], [alias templates], [type inference][decltype]
and [constant expressions][constexpr] to the core language.
-This powerful C++11 machinery enabled the development of whole new
+The powerful C++11 machinery enabled the development of whole new
metaprogramming [styles][tmp.simple] and [techniques][tmp.modern] with
potential to outperform Boost.MPL by orders of magnitude in many instances.
Moreover, the need for endless automatically generated boilerplate code could
@@ -56,7 +44,7 @@ finally be overcome using variadic templates,
whereas syntax clutter could be mitigated using alias templates,
vastly improving readability.
-Eventually, [motivation][mpl.lite] to modernize Boost.MPL emerged from the
+Eventually, [motivation][mpl.lite] to modernize Boost.MPL emerged from the Boost
community, even though opinions diverged widely on the matter.
As diverse has been the development of new metaprogramming libraries
with varying degrees of success,
@@ -65,8 +53,8 @@ Louis Dionne, the latter formally accepted into the Boost distribution in July
2015.
Metal is yet another approach to modern C++11 metaprogramming.
-Its ultimate goal is to be regarded as the best alternative to Boost.MPL in
-every use case where support for C++11 is desired,
+Its ultimate goal is to be regarded as the natural successor of Boost.MPL in
+every use case where C++11 is available,
delivering greater performance and expressiveness without
cluttering the codebase.
Although not a perfect drop in replacement for Boost.MPL,
@@ -79,7 +67,7 @@ Getting Started {#getting_started}
It's very easy to start enjoying metaprogramming with Metal,
being header-only with no external dependencies,
-all you have to do is download and optionally install it system-wide.
+all you have to do is download it.
Downloading {#downloading}
--------------------------------------------------------------------------------
@@ -93,7 +81,7 @@ you can clone current stable branch `master` from GitHub.
git clone https://github.com/brunocodutra/metal
-Likewise, the [bleeding edge] development version can be obtained by cloning
+Likewise, the bleeding edge development version can be obtained by cloning
branch `develop` instead.
git clone https://github.com/brunocodutra/metal --branch=develop
@@ -124,14 +112,14 @@ From within an empty directory issue the following commands.
Unless otherwise specified,
Metal's include tree will be copied into the default prefix
for locally installed libraries in your platform,
-that is `/usr/local/include` on [Unix[-like]][unix-like] systems and
+that is `/usr/local/include` on Unix[-like] systems and
`C:\Program Files\Metal\include` on Windows.
Simply add the installation prefix to the include search path of your
-compiler/project if it hasn't been already, and you're good to go.
+compiler/project if it isn't by default, and you're good to go.
If your project uses [CMake],
Metal may also be integrated into your project via `find_package`,
-whereupon `METAL_INCLUDE_DIRS` will be set to contain
+whereupon `METAL_INCLUDE_DIRS` is set to contain
all necessary include prefixes.
In short, simply add the following to the `CMakeLists.txt` of your project.
@@ -143,7 +131,7 @@ For more information, please refer to [CMake documentation][CMake.doc].
Documentation {#documentation}
--------------------------------------------------------------------------------
-An offline copy of this documentation website may be obtained by cloning
+An offline copy of this documentation may be obtained by cloning
branch `gh-pages`.
git clone https://github.com/brunocodutra/metal --branch=gh-pages
@@ -158,7 +146,7 @@ From within an empty directory issue the following commands.
The documentation will be generated into `doc/html/`.
To browse the documentation offline,
-simply load `index.html` on your favorite web browser.
+simply load `index.html` on any web browser that supports [JavaScript].
Portability {#portability}
================================================================================
@@ -166,8 +154,7 @@ Portability {#portability}
Great effort is undertaken to keep Metal strictly in conformance with the C++11
standard and compatible with the widest possible variety of compilers.
To this end, some of the most popular freely available C++ compilers are
-officially and actively supported through [Continuous Integration (CI)][ci]
-premisses.
+actively supported through [Continuous Integration (CI)][ci] premisses.
GCC and Clang are tested with help of [Travis CI][travis.metal],
while Microsoft Visual Studio is tested using [Appveyor CI][appveyor.metal].
@@ -265,7 +252,7 @@ specialization of [std::integral_constant][integral].
### See Also
-metal::number, metal::boolean, metal::integer
+metal::number, metal::boolean, metal::integer, metal::character
Optional {#concepts_optional}
--------------------------------------------------------------------------------
@@ -276,7 +263,7 @@ represent either *just* some other [Value] or *nothing*.
In order to *evaluate* an [Optional]
one must explicitly name its nested `::type`.
An [Optional] is said to be empty,
-whenever a nested `::type` is undefined or ambiguously defined,
+whenever a nested [Value] called `::type` is undefined or ambiguously defined,
thus attempting to *evaluate* an empty [Optional] leads to a compile-time error.
\tip{
@@ -286,7 +273,7 @@ for any [Optional] `opt`.
### Requirements
-Any type is an [Optional].
+Any [Value] is also an [Optional].
### Examples
@@ -313,16 +300,16 @@ In general, however, an [Expression] may be *empty* for some set of arguments,
thus attempting to *evaluate* such an [Expression] for such set of arguments
leads to a compile-time error.
-\note{
-Because [Expressions] are not themselves [Values],
-it is not possible to write [higher-order] expressions.
-}
-
### Requirements
`expr` is a model of [Expression] if and only if `expr` is a
template class, union or alias that only expects types as arguments.
+\note{
+Because [Expressions] are not themselves [Values],
+it is not possible to define [higher-order] expressions directly.
+}
+
### Examples
\snippet concepts/expression.cpp ex1
@@ -349,20 +336,20 @@ the [Lambda Calculus].
### Requirements
-Any type is a [Lambda].
+Any [Value] is also a [Lambda].
### Semantics
Let `expr` be an [Expression], `[a1, ..., ai, ..., an]` atomic [Values],
`[_1, ..., _i, ..., _n]` [Placeholders] and `[l1, ..., li, ..., ln]` [Lambdas].
-* Invoking `ai` for any (possibly empty) set of [Values] yields `ai`
-* Invoking `_i` for `[a1, ..., ai, ..., an]` yields `ai`
-* Invoking `metal::lambda` for `[a1, ..., an]` yields
+* Invoking `ai` with any (possibly empty) set of [Values] yields `ai`
+* Invoking `_i` with `[a1, ..., ai, ..., an]` yields `ai`
+* Invoking `metal::lambda` with `[a1, ..., an]` yields
`expr::type`
-* Invoking `expr` for `[a1, ..., an]`
-invokes `metal::lambda` for the set of [Values] yielded by
-invoking each `li` for `[l1, ..., ln]`.
+* Invoking `expr` with `[a1, ..., an]`
+invokes `metal::lambda` with the [Values] yielded by
+recursively invoking each `li` with `[a1, ..., an]`.
\tip{
`metal::lambda` can be used to adapt any [Expression] `expr`
@@ -388,7 +375,7 @@ A [List] is a sequence of [Values].
### Requirements
-A [List] is any specialization of any template class or union,
+A [List] is any specialization of any template class or union
that only expects types as arguments.
### Examples
@@ -436,7 +423,7 @@ each of which is associated with another [Value].
A [Map] is a [List] of [Pairs], whose first elements are all distinct, that is
- [[k0, v0], ..., [kn, vn]]; ki != kj for all i, j in {0, n}
+ [[k0, v0], ..., [kn, vn]]; ki != kj for all i, j in {0, n} and i != j
### Examples
@@ -456,25 +443,32 @@ Data-Code Duality {#concepts_duality}
================================================================================
Markedly influenced by various functional programming languages,
-such as [Haskell] and [SML], Metal owes much of its design to [Lisp]
-in particular.
+such as [Haskell] and [SML],
+Metal owes much of its design particularly to [Lisp].
From it, Metal borrowed [s-expressions] and
the notion that data structures and algorithms are nothing
-but [two sides of the same coin][homoiconicity].
+but [two sides of the same coin][homoiconicity], that is,
+Metal makes no difference between lists and unevaluated expressions.
+
+Take for instance the following definition.
+
+\snippet manual/homoiconicity.cpp 1
+
+Here `sum` could be understood as an unevaluated addition of three numbers, thus
-Much like Lisp, Metal makes no difference between lists and unevaluated
-expressions.
-The following, for example, could be seen as an unevaluated expression
-that represents the sum of two numbers.
+\snippet manual/homoiconicity.cpp 2
-\snippet manual.cpp sum
+Alternativelly, `sum` could also be seen as a [List] that contains three values
-Just as accurately, it could also be seen as a pair.
+\snippet manual/homoiconicity.cpp 3
-\snippet manual.cpp first
-\snippet manual.cpp second
+Now, just like any [List], `sum` may be transformed into a new [List]
-Now that may look silly put in a simple example like this one, but [...]
+\snippet manual/homoiconicity.cpp 4
+
+... which in turn may be seen as the sum of the squares of the same three numbers.
+
+\snippet manual/homoiconicity.cpp 5
\tip{
To save typing, most [Expressions] in Metal have an associated eager adaptor
@@ -483,6 +477,200 @@ given an expression `metal::expr`,
`metal::expr_t<...>` is equivalent to `typename metal::expr<...>::type`.
}
+Metal in Action {#metal_in_action}
+================================================================================
+
+Enough theory, lets see some action!
+
+Parsing Raw Literals {#parsing_raw_literals}
+--------------------------------------------------------------------------------
+
+If you ever considered augmenting [`std::tuple`][tuple],
+so that instead of the rather odd [`std::get()`][get]
+
+\snippet tutorial/literal.cpp teaser_1
+
+one could just use the more intuitive subscript operator `[N]`,
+
+\strike{
+\snippet tutorial/literal.cpp teaser_2
+}
+
+chances are you realized the hard way
+that the reason why such an operator is not overloaded by default is because
+there's simply no way of overloading such an operator!
+
+All is not lost however if you can live with the subscript operator taking an
+object of type `std::integral_constant`, or in Metal's parlance [Number],
+instead of an usual integral value.
+
+\snippet tutorial/literal.cpp super_tuple
+
+\snippet tutorial/literal.cpp teaser_3
+
+Neat isn't it?
+Now we need a [literal operator][literal] `_c` that encodes an integral value
+as a [Number]. Sounds simple enough, right?
+
+\strike{
+\snippet tutorial/literal.cpp naive
+}
+
+Not really. While `constexpr` tells the compiler the value returned by
+`operator ""_c` might be a compile time constant,
+it tells no such thing about its argument.
+We are thus left no other option but to parse raw literals ourselves,
+in other words, we are in for some fun!
+
+### The Raw Literal Operator Template
+
+Raw literal operator templates are defined as a nullary function templated over
+`char...`, such as
+
+\snippet tutorial/literal.cpp raw
+
+where `tokens...` are mapped to the exact characters that make up the literal,
+including the prefixes `0x` and `0b`
+
+\snippet tutorial/literal.cpp raw_examples_1
+
+as well as the digit separator `'` introduced by [C++14]
+
+\snippet tutorial/literal.cpp raw_examples_2
+
+### The `operator ""_c`
+
+We start by defining our very own literal operator `_c`.
+It simply wraps each token into a `metal::character` and forwards them to an
+[Expression] that effectively parses the [Number], we'll call it,
+suggestively, `make_number`.
+
+\snippet tutorial/literal.cpp _c
+
+### Resolving the Radix
+
+In its turn `make_number` strips the prefix, if any, thus resolving the radix,
+then forwards the remaining tokens to `parse_digits`,
+which is in charge of translating the raw characters to a [List] of
+integral [Numbers].
+The radix and digits are then forwarded to `compute`, which adds up the digits
+according to the radix.
+
+\snippet tutorial/literal.cpp make_number
+
+Notice that we followed the notation used by Metal and defined `make_number_t`
+as an alias to `typename make_number<>::type` to save typing.
+
+### Parsing the Digits
+
+To parse the characters into the corresponding integral, we need first to remove
+all digit separators.
+That can be easily accomplished using `metal::remove`, which takes a [List] `l`
+and a [Value] `v` and returns another [List] that contains every element from
+`l` and in the same order, except for those that are identical to `v`.
+
+\snippet tutorial/literal.cpp remove
+
+The remaining digits can then be transformed into the corresponding
+[Numbers] using `metal::transform`, which takes a [Lambda] `lbd` and a
+[List] `l` and returns another [List] containing the results of *invoking* `lbd`
+for each element in `l`.
+
+ [lbd(l[0]), lbd(l[1]), ..., lbd(l[n-2]), lbd(l[n-1])]
+
+First we need an [Expression] that maps characters to
+[Numbers] from which we can construct our `lbd`.
+We'll call it `to_number` and it is rather trivial.
+
+\snippet tutorial/literal.cpp to_number
+
+Now we can transform characters to [Numbers].
+
+\snippet tutorial/literal.cpp transform_1
+
+That peculiar `metal::_1` is a placeholder and it works like this:
+when `to_number` is invoked with some argument,
+`metal::_1` will be substituted for that argument and only then `to_number`
+is *evaluated*.
+
+Putting it all together we have
+
+\snippet tutorial/literal.cpp parse_digits
+
+### Computing the Number
+
+Now we turn our attention to `compute`.
+It takes the radix and a list of [Numbers] representing the digits and is in
+charge of adding up the digits according to the radix, that is
+
+ D0*radix^(n-1) + D1*radix^(n-2) + ... + D{n-2}*radix + D{n-1}
+
+The first thing we notice is that the *ith* digit actually corresponds to the
+(n-1-i)th power of the radix, so, to make things simpler,
+we need to `metal::reverse` the order of digits.
+
+\snippet tutorial/literal.cpp reverse
+
+Then we have
+
+ D0 + D1*radix + ... + D{n-2}*radix^(n-2) + D{n-1}*radix^(n-1)
+
+Now we need to `metal::enumerate` the exponents that correspond to each digit.
+
+\snippet tutorial/literal.cpp enumerate
+
+This version of `metal::enumerate` takes two [Numbers], `start` and `size`,
+and returns a [List] containing a sequence of [Numbers] beginning with `start`
+and ending in `size - 1`.
+
+ [start, start + 1, ..., size - 2, size - 1]
+
+\note{
+All [Numbers] in the sequence have the same type as `start`
+regardless of the type of `size`.
+}
+
+The next step is to compute each term of the sum.
+We'll be using `metal::transform` again, but this time it takes a *binary*
+[Lambda] `lbd` and two [Lists] `l1` and `l2` and returns a new [List] formed by
+*invoking* `lbd` for the elements of `l1` and `l2` pairwise.
+
+ [lbd(l1[0], l2[0]), lbd(l1[1], l2[1]), ..., lbd(l1[n-2], l2[n-2]), lbd(l1[n-1], l2[n-1])]
+
+\snippet tutorial/literal.cpp transform_2
+
+Here again `metal::_1` and `metal::_2` are placeholders that get substituted for
+the first and second arguments with which `lbd` is invoked,
+prior to the recursive *evaluation* of the [Expressions] that form the [Lambda].
+
+Finally we need to sum up the terms, so basically we need to invoke `metal::add`
+for the elements contained in a [List].
+That's exactly what `metal::apply` is for.
+
+\snippet tutorial/literal.cpp sum
+
+Here we used `metal::lambda` which is basically a synonym for
+`metal::add, metal::arg>`,
+where `n` is the number of arguments with which `metal::lambda` is
+invoked, that is the size of the [List] in this particular case.
+This way we don't need to care about the actual number of arguments.
+
+We now have all the pieces needed to define `compute`.
+
+\snippet tutorial/literal.cpp compute
+
+And we are done.
+
+\snippet tutorial/literal.cpp test_1
+
+It even works for very long binary literals.
+
+\snippet tutorial/literal.cpp test_2
+
+And also ignores digit separators.
+
+\snippet tutorial/literal.cpp test_3
+
[Value]: \ref concepts_value
[Values]: \ref concepts_value
[Optional]: \ref concepts_optional
@@ -502,30 +690,30 @@ given an expression `metal::expr`,
[Placeholders]: \ref placeholders
[C++11]: http://en.wikipedia.org/wiki/C%2B%2B11
-[STL]: http://en.wikipedia.org/wiki/Standard_Template_Library
-[pola]: http://en.wikipedia.org/wiki/Principle_of_least_astonishment
-[simplicity]: http://en.wikipedia.org/wiki/Simplicity#Quotes_about_simplicity
-[expressiveness]: http://en.wikipedia.org/wiki/Expressive_power_%28computer_science%29
+[C++14]: http://en.wikipedia.org/wiki/C%2B%2B14
+[JavaScript]: http://en.wikipedia.org/wiki/JavaScript
[higher-order]: http://en.wikipedia.org/wiki/Higher-order_lambda
[first-class]: http://en.wikipedia.org/wiki/First-class_citizen
[Lambda Calculus]: http://en.wikipedia.org/wiki/Lambda_calculus
[s-expressions]: http://en.wikipedia.org/wiki/S-expression
[homoiconicity]: http://en.wikipedia.org/wiki/Homoiconicity
[ci]: http://en.wikipedia.org/wiki/Continuous_integration
-[bleeding edge]: http://en.wikipedia.org/wiki/Bleeding_edge_technology
-[unix-like]: http://en.wikipedia.org/wiki/Unix-like
[tmp]: http://en.wikipedia.org/wiki/Template_metaprogramming
[tmp.turing]: http://ubietylab.net/ubigraph/content/Papers/pdf/CppTuring.pdf
[tmp.simple]: http://pdimov.com/cpp2/simple_cxx11_metaprogramming.html
[tmp.modern]: http://pdimov.com/cpp2/simple_cxx11_metaprogramming_2.html
+[algorithm]: http://en.cppreference.com/w/cpp/algorithm
[preprocessor]: http://en.wikipedia.org/wiki/C_preprocessor
[variadics]: http://en.cppreference.com/w/cpp/language/parameter_pack
[alias templates]: http://en.cppreference.com/w/cpp/language/type_alias
[decltype]: http://en.cppreference.com/w/cpp/language/decltype
[constexpr]: http://en.cppreference.com/w/cpp/language/constexpr
[integral]: http://en.cppreference.com/w/cpp/types/integral_constant
+[tuple]: http://en.cppreference.com/w/cpp/utility/tuple
+[get]: http://en.cppreference.com/w/cpp/utility/tuple/get
+[literal]: http://en.cppreference.com/w/cpp/language/user_literal
[CMake]: http://cmake.org/
[CMake.doc]: http://cmake.org/documentation/
diff --git a/example/include/example.hpp b/example/include/example.hpp
index 4a8d4f9f..c05262b2 100644
--- a/example/include/example.hpp
+++ b/example/include/example.hpp
@@ -8,7 +8,7 @@
#define CAT_(X, Y) X##Y
#define CAT(X, Y) CAT_(X, Y)
-#define ANONYMOUS(SCOPE) SCOPE CAT(anonymous, __LINE__)
+#define HIDDEN(SCOPE) SCOPE CAT(anonymous, __LINE__)
int main()
{
diff --git a/example/src/concepts/expression.cpp b/example/src/concepts/expression.cpp
index f9ab21b9..56ac9f69 100644
--- a/example/src/concepts/expression.cpp
+++ b/example/src/concepts/expression.cpp
@@ -8,7 +8,7 @@
#include "example.hpp"
-ANONYMOUS(namespace)
+HIDDEN(namespace)
{
/// [ex1]
template
@@ -21,7 +21,7 @@ union expr
static_assert(metal::is_just>::value, "");
}
-ANONYMOUS(namespace)
+HIDDEN(namespace)
{
/// [ex2]
template
@@ -34,7 +34,7 @@ struct expr
static_assert(!metal::is_just>::value, "");
}
-ANONYMOUS(namespace)
+HIDDEN(namespace)
{
/// [ex3]
template //evaluable for array types
@@ -46,31 +46,31 @@ static_assert(metal::is_just>::value, "");
static_assert(metal::is_just>::value, "");
}
-ANONYMOUS(namespace)
+HIDDEN(namespace)
{
/// [nex1]
-struct not_an_expr //not a template
+struct not_an_expression //not a template
{
struct type;
};
/// [nex1]
}
-ANONYMOUS(namespace)
+HIDDEN(namespace)
{
/// [nex2]
template class... exprs> //non-type parameter
-struct not_an_expr
+struct not_an_expression
{
struct type;
};
/// [nex2]
}
-ANONYMOUS(namespace)
+HIDDEN(namespace)
{
/// [nex3]
template //non-type parameter
-using not_an_expr = std::integral_constant;
+using not_an_expression = std::integral_constant;
/// [nex3]
}
diff --git a/example/src/concepts/lambda.cpp b/example/src/concepts/lambda.cpp
index 4d56da67..adf1e10b 100644
--- a/example/src/concepts/lambda.cpp
+++ b/example/src/concepts/lambda.cpp
@@ -8,7 +8,7 @@
#include "example.hpp"
-ANONYMOUS(namespace)
+HIDDEN(namespace)
{
/// [ex1]
using lbd = void;
@@ -17,7 +17,7 @@ using lbd = void;
static_assert(std::is_same**/metal::invoke_t, void>::value, "");
}
-ANONYMOUS(namespace)
+HIDDEN(namespace)
{
/// [ex2]
using lbd = metal::_2;
@@ -26,7 +26,7 @@ using lbd = metal::_2;
static_assert(std::is_same**/metal::invoke_t, int>::value, "");
}
-ANONYMOUS(namespace)
+HIDDEN(namespace)
{
/// [ex3]
using lbd = metal::lambda;
@@ -35,7 +35,7 @@ using lbd = metal::lambda;
static_assert(std::is_same**/metal::invoke_t, void*>::value, "");
}
-ANONYMOUS(namespace)
+HIDDEN(namespace)
{
/// [ex4]
using lbd = std::add_pointer;
@@ -44,7 +44,7 @@ using lbd = std::add_pointer;
static_assert(std::is_same**/metal::invoke_t, void*>::value, "");
}
-ANONYMOUS(namespace)
+HIDDEN(namespace)
{
/// [ex5]
using lbd = std::is_convertible**/metal::_1, std::add_pointer**/metal::_2>>;
diff --git a/example/src/concepts/list.cpp b/example/src/concepts/list.cpp
index 43a1c0c6..957e4e9d 100644
--- a/example/src/concepts/list.cpp
+++ b/example/src/concepts/list.cpp
@@ -8,7 +8,7 @@
#include "example.hpp"
-ANONYMOUS(namespace)
+HIDDEN(namespace)
{
/// [ex1]
template
@@ -21,7 +21,7 @@ static_assert(metal::is_list_t::value, "");
static_assert(metal::size_t::value == 1, "");
}
-ANONYMOUS(namespace)
+HIDDEN(namespace)
{
/// [ex2]
template
@@ -34,16 +34,16 @@ static_assert(metal::is_list_t::value, "");
static_assert(metal::size_t::value == 0, "");
}
-ANONYMOUS(namespace)
+HIDDEN(namespace)
{
/// [nex1]
-using not_a_list = union{}; // not a template instantiation
+using not_a_list = struct{}; // not a template instantiation
/// [nex1]
static_assert(!metal::is_list_t::value, "");
}
-ANONYMOUS(namespace)
+HIDDEN(namespace)
{
/// [nex2]
template
diff --git a/example/src/concepts/map.cpp b/example/src/concepts/map.cpp
index f4a8af56..8d31282c 100644
--- a/example/src/concepts/map.cpp
+++ b/example/src/concepts/map.cpp
@@ -8,7 +8,7 @@
#include "example.hpp"
-ANONYMOUS(namespace)
+HIDDEN(namespace)
{
/// [ex1]
template
@@ -23,7 +23,7 @@ using map = many, many, couple>;
static_assert(metal::is_map_t