Skip to content

Commit 4b310e2

Browse files
committed
Merge branch 'cleanup' into v2
2 parents 0d11261 + 2fefc01 commit 4b310e2

24 files changed

+970
-786
lines changed

docs.in/reference/apply_product.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ the n-fold Cartesian product of the input `mp_list` lists.
2626
#include <yorel/yomm2/templates.hpp>
2727

2828
using namespace yorel::yomm2;
29-
using boost::mp11::mp_list;
29+
using detail::types;
3030

3131
struct a;
3232
struct b;
@@ -41,10 +41,10 @@ static_assert(
4141
std::is_same_v<
4242
apply_product<
4343
templates<bin1, bin2>,
44-
mp_list<a, b>,
45-
mp_list<x, y, z>
44+
types<a, b>,
45+
types<x, y, z>
4646
>,
47-
mp_list<
47+
types<
4848
bin1<a, x>, bin1<a, y>, bin1<a, z>,
4949
bin1<b, x>, bin1<b, y>, bin1<b, z>,
5050

docs.in/reference/product.cpp

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ headers:yorel/yomm2/templates.hpp>
66
template<typename... TypeLists>
77
using product = /*unspecified*/;
88
```
9-
`product` takes a list of ->mp_list lists, and evaluates to a `mp_list` list
9+
`product` takes a list of ->types lists, and evaluates to a `types` list
1010
consisting of the n-fold Cartesian product of the input lists.
1111

1212
## Example
@@ -19,11 +19,9 @@ consisting of the n-fold Cartesian product of the input lists.
1919

2020
#include <type_traits>
2121
#include <yorel/yomm2/core.hpp>
22-
#include <yorel/yomm2/compiler.hpp>
2322
#include <yorel/yomm2/templates.hpp>
2423

2524
namespace yomm2 = yorel::yomm2;
26-
using boost::mp11::mp_list;
2725

2826
struct a;
2927
struct b;
@@ -34,12 +32,12 @@ struct z;
3432
static_assert(
3533
std::is_same_v<
3634
yomm2::product<
37-
mp_list<a, b>,
38-
mp_list<x, y, z>
35+
yomm2::types<a, b>,
36+
yomm2::types<x, y, z>
3937
>,
40-
mp_list<
41-
mp_list<a, x>, mp_list<a, y>, mp_list<a, z>,
42-
mp_list<b, x>, mp_list<b, y>, mp_list<b, z>
38+
yomm2::types<
39+
yomm2::types<a, x>, yomm2::types<a, y>, yomm2::types<a, z>,
40+
yomm2::types<b, x>, yomm2::types<b, y>, yomm2::types<b, z>
4341
>
4442
>);
4543

docs.in/tutorials/templates_tutorial.cpp

Lines changed: 53 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -19,13 +19,12 @@ std::ostream &operator<<(std::ostream &os, const std::type_info &ti) {
1919

2020
#define elided
2121

22-
#include <yorel/yomm2/core.hpp>
2322
#include <yorel/yomm2/compiler.hpp>
23+
#include <yorel/yomm2/core.hpp>
2424
#include <yorel/yomm2/symbols.hpp>
2525
#include <yorel/yomm2/templates.hpp>
2626

2727
using namespace yorel::yomm2;
28-
using boost::mp11::mp_list;
2928

3029
// md<
3130

@@ -229,7 +228,6 @@ vector reals(new concrete_vector<double>{4., 5., 6.});
229228

230229
// code<
231230
#include <yorel/yomm2/core.hpp>
232-
#include <yorel/yomm2/compiler.hpp>
233231
#include <yorel/yomm2/symbols.hpp>
234232

235233
using namespace yorel::yomm2;
@@ -293,9 +291,9 @@ inline bool operator==(const vector& a, const vector& b) {
293291
// ```
294292

295293
// This "closed" approach is lazy, and defies the purpose of *open* methods. It
296-
// is not for the author of the library to decide which mp_list to support. The
294+
// is not for the author of the library to decide which types to support. The
297295
// user may have no interest in integer vectors, but may need `complex` vectors.
298-
// Or vectors of `decimal` floating-point numbers. Or, mp_list from another
296+
// Or vectors of `decimal` floating-point numbers. Or, types from another
299297
// library, or perhaps created by the user himself. An advanced user may also
300298
// want to add new operations or vector subtypes (like large sparse vectors).
301299
// All this must be possible, and not unduly complex. Extensibility is what open
@@ -311,14 +309,14 @@ inline bool operator==(const vector& a, const vector& b) {
311309
// 1. Put the definitions in one or several templates, where the method being
312310
// defined is the first template argument.
313311
// 2. Create a meta-function that generates interesting combinations of methods
314-
// and mp_list.
312+
// and types.
315313
// 3. Instantiate the container(s) for these combinations. The resulting classes
316314
// must satisfy the requirements of a definition container, *or* be derived
317315
// from class `not_defined`. Add the definition containers to the method,
318316
// extracted from the first template argument.
319317

320318
// The meta-programming library comprises:
321-
// - containers for mp_list and templates
319+
// - containers for types and templates
322320
// - meta-functions that generate Cartesian products of these containers.
323321
// - a mechanism for instantiating the resulting definitions.
324322

@@ -328,7 +326,7 @@ inline bool operator==(const vector& a, const vector& b) {
328326
// 1. Make it very easy for a new user to use the library with all the defaults.
329327
// 2. Make it easy for a "normal" user to specify which parts of the library to
330328
// use.
331-
// 3. Make it possible for an advanced user to extend the library with new mp_list
329+
// 3. Make it possible for an advanced user to extend the library with new types
332330
// and new operations.
333331

334332
// Let's apply these ideas to the `vector` methods. First we declare a container
@@ -344,7 +342,7 @@ struct definition;
344342
// md<
345343

346344
// Let's create partial specializations that defines addition, subtraction and
347-
// comparison for vectors or two underlying mp_list:
345+
// comparison for vectors or two underlying types:
348346

349347
// >
350348

@@ -403,15 +401,15 @@ struct definition<comparison, T, U> {
403401
// ...then add the resulting definitions to their respective method.
404402

405403
// For the Cartesian product, we can use two constructs provided by YOMM2: the
406-
// `mp_list` container, and the `product` meta-function.
404+
// `types` container, and the `product` meta-function.
407405

408-
// `mp_list<typename...>` is a simple list of mp_list. It is similar to Boost.Mp11's
409-
// `mp_list`. Unlike `mp_list`, `mp_list` does not have a body. This helps detect
406+
// `types<typename...>` is a simple list of types. It is similar to Boost.Mp11's
407+
// `mp_list`. Unlike `mp_list`, `types` does not have a body. This helps detect
410408
// meta-programming bugs.
411409

412-
// `product<typename... TypeLists>` takes any number of `mp_list` lists, and
413-
// returns a `mp_list` list containing all the combinations of one element taken
414-
// from each input list, each combination being itself wrapped in a `mp_list`. For
410+
// `product<typename... TypeLists>` takes any number of `types` lists, and
411+
// returns a `types` list containing all the combinations of one element taken
412+
// from each input list, each combination being itself wrapped in a `types`. For
415413
// example:
416414

417415
// >
@@ -421,12 +419,12 @@ struct definition<comparison, T, U> {
421419
static_assert(
422420
std::is_same_v<
423421
product<
424-
mp_list<int, double>,
425-
mp_list<int, double, float>
422+
types<int, double>,
423+
types<int, double, float>
426424
>,
427-
mp_list<
428-
mp_list<int, int>, mp_list<int, double>, mp_list<int, float>,
429-
mp_list<double, int>, mp_list<double, double>, mp_list<double, float>
425+
types<
426+
types<int, int>, types<int, double>, types<int, float>,
427+
types<double, int>, types<double, double>, types<double, float>
430428
>
431429
>);
432430

@@ -456,9 +454,9 @@ use_classes<
456454
use_definitions<
457455
definition,
458456
product<
459-
mp_list<addition, subtraction, comparison>,
460-
mp_list<int, double>,
461-
mp_list<int, double>
457+
types<addition, subtraction, comparison>,
458+
types<int, double>,
459+
types<int, double>
462460
>
463461
> YOMM2_GENSYM;
464462

@@ -506,7 +504,7 @@ BOOST_AUTO_TEST_CASE(test_vectors) {
506504
// ## Writing a user-friendly instantiation function
507505

508506
// Now we have everything we need to write a single template that allows users
509-
// to initialize the library for the mp_list they need. For that we use
507+
// to initialize the library for the types they need. For that we use
510508
// `std::tuple` to lump teh registration object together:
511509

512510
// >
@@ -523,9 +521,9 @@ using use_vector_library = std::tuple<
523521
use_definitions<
524522
definition,
525523
product<
526-
mp_list<addition, subtraction, comparison>,
527-
mp_list<NumericTypes...>,
528-
mp_list<NumericTypes...>
524+
types<addition, subtraction, comparison>,
525+
types<NumericTypes...>,
526+
types<NumericTypes...>
529527
>
530528
>
531529
>;
@@ -535,7 +533,7 @@ using use_vector_library = std::tuple<
535533
// md<
536534

537535
// All the user of the library needs to do now is to create an instance (object)
538-
// of `use_vector_library`, instantiated with the required mp_list:
536+
// of `use_vector_library`, instantiated with the required types:
539537

540538
// >
541539

@@ -606,7 +604,7 @@ use_vector_library<int, double> init_vectors;
606604

607605
// For brevity, we will consider only ordinary (i.e. non-square), square and
608606
// symmetric matrices. Also, we will omit all maths and storage management, to
609-
// focus on dealing with mp_list.
607+
// focus on dealing with types.
610608

611609
// Here is the implementation of these classes, and the intermediary abstract
612610
// classes:
@@ -702,7 +700,7 @@ struct symmetric : any_symmetric<T> {
702700
// importantly, better interfaces. For example, square matrices have a
703701
// determinant, which ordinary matrices do not have. Also, type errors can be
704702
// diagnosed by the compiler. However, compile-time specialization is possible
705-
// only if the mp_list of the matrices is known in advance. It may not always be
703+
// only if the types of the matrices is known in advance. It may not always be
706704
// the case.
707705

708706
// Thus, as library designers, we face a dilemma: which users to serve best?
@@ -909,7 +907,7 @@ auto operator~(const handle<Matrix<T>>& m) {
909907
// 1. `Matrix` is actually one of our `matrix` templates; without (1), *any*
910908
// template would match.
911909
// 2. `Matrix<T>` is abstract; without (2), we would have an ambiguity with our
912-
// own `operator~` defined above for concrete matrix mp_list.
910+
// own `operator~` defined above for concrete matrix types.
913911

914912
// C++20 concepts offer a much cleaner solution for taming template
915913
// instantiations.
@@ -919,7 +917,7 @@ auto operator~(const handle<Matrix<T>>& m) {
919917
// methods, e.g. `negate`. For that we use a templatized definition container
920918
// called `unary_definition`. We want to instantiate it for every combination of
921919
// method template, abstract base class, concrete implementation of the abstract
922-
// class, and this for the required numeric mp_list. E.g.:
920+
// class, and this for the required numeric types. E.g.:
923921
// - `transpose<any<int>>`, `any<int>`, `ordinary<int>`
924922
// - `transpose<any<int>>`, `any_square`, `square`
925923
// - `transpose<any<int>>`, `any_square`, `symmetrical`
@@ -939,22 +937,22 @@ auto operator~(const handle<Matrix<T>>& m) {
939937
// M = { unary method templates: transpose, negate, etc }
940938
// A = { abstract class templates }
941939
// C = { concrete class templates }
942-
// T = { required numeric mp_list }
940+
// T = { required numeric types }
943941
// ```
944942

945943
// ...and selecting the combinations that satisfy the condition:
946944
// - `A<T>` is a base of `C<T>`
947945

948946
// This time, we need to make a Cartesian product that involves templates as
949-
// well as mp_list. For this, YOMM2 provides two constructs:
947+
// well as types. For this, YOMM2 provides two constructs:
950948
// - `template_<template<typename...> typename>` wraps a template in a type. It
951949
// contains a nested template `fn<typename...Ts>`, which applies the original
952950
// template to `Ts...`. Thus we have the identity:
953951
// ```
954952
// template_<F>::template fn<Ts...> = F<Ts...>
955953
// ```
956954
// - `templates<template<typename...> typename...>` wraps a list of templates in
957-
// a `mp_list` list of `template_`s.
955+
// a `types` list of `template_`s.
958956

959957
// We can now implement `unary_definition`:
960958

@@ -1032,27 +1030,27 @@ use_definitions<
10321030
unary_definition,
10331031
product<
10341032
templates<transpose>, abstract_matrix_templates,
1035-
concrete_matrix_templates, mp_list<double, int>>>
1033+
concrete_matrix_templates, types<double, int>>>
10361034
YOMM2_GENSYM;
10371035
// >
10381036

10391037
// md<
10401038

10411039
// We must not forget to register all the matrix classes, for both numeric
1042-
// mp_list. For that, we can use another YOMM2 helper: `apply_product`. It takes a
1043-
// `templates` list, and any number of `mp_list` list; forms the Cartesian
1040+
// types. For that, we can use another YOMM2 helper: `apply_product`. It takes a
1041+
// `templates` list, and any number of `types` list; forms the Cartesian
10441042
// product; and, for each resulting combination, applies the first element - a
1045-
// template - to the other elements. The result is a `mp_list` list of template
1043+
// template - to the other elements. The result is a `types` list of template
10461044
// instantiations.
10471045

10481046
// We saw that `use_classes` takes a list of classes. It also works with a
1049-
// list of `mp_list` lists. We can thus inject the result of `apply_product` into
1047+
// list of `types` lists. We can thus inject the result of `apply_product` into
10501048
// `use_classes`:
10511049

10521050
// >
10531051

10541052
// code<
1055-
YOMM2_STATIC(use_classes<apply_product<matrix_templates, mp_list<double, int>>>);
1053+
YOMM2_STATIC(use_classes<apply_product<matrix_templates, types<double, int>>>);
10561054
// >
10571055

10581056
#endif
@@ -1088,12 +1086,12 @@ BOOST_AUTO_TEST_CASE(test_dynamic_transpose) {
10881086
// `any_square<double>`.
10891087

10901088
// Fortunately, we can leverage the static `operator+` to deduce the return type
1091-
// of additions that involve one or two abstract mp_list. This is what the nested
1092-
// `abstract_type` and `concrete_type` aliases are for. We can convert the mp_list
1089+
// of additions that involve one or two abstract types. This is what the nested
1090+
// `abstract_type` and `concrete_type` aliases are for. We can convert the types
10931091
// of the arguments to their nearest concrete type: for a
10941092
// `any_symmetric<double>`, it is a `symmetric<double>`; for a `square<double>`,
10951093
// it is `square<double>`. Then we can "pretend" to add two handles to objects
1096-
// of the two mp_list, and extract the result's type using `decltype`. And
1094+
// of the two types, and extract the result's type using `decltype`. And
10971095
// finally, we convert that type to its abstract base class, using
10981096
// `abstract_type`.
10991097

@@ -1182,7 +1180,7 @@ auto operator+(const handle<M1>& a, const handle<M2>& b) {
11821180
// M = { unary method templates: transpose, negate, etc }
11831181
// A1, A2 = { abstract class templates }
11841182
// C1, C2 = { concrete class templates }
1185-
// T1, T2 = { required numeric mp_list }
1183+
// T1, T2 = { required numeric types }
11861184
// ```
11871185

11881186
// ...and selecting the combinations that satisfy the condition:
@@ -1287,8 +1285,8 @@ use_definitions<
12871285
binary_definition,
12881286
product<
12891287
templates<add>, abstract_matrix_templates, concrete_matrix_templates,
1290-
mp_list<double, int>, abstract_matrix_templates,
1291-
concrete_matrix_templates, mp_list<double, int>>>
1288+
types<double, int>, abstract_matrix_templates,
1289+
concrete_matrix_templates, types<double, int>>>
12921290
YOMM2_GENSYM;
12931291
// >
12941292

@@ -1326,7 +1324,7 @@ BOOST_AUTO_TEST_CASE(test_dynamic_operations) {
13261324
// Now we need to create a mechanism that enable users to instantiate just the
13271325
// method definitions they want. This is more complicated than for the vector
13281326
// library, because users need to be able to select from three sets: the
1329-
// underlying numeric mp_list, the matrix mp_list, and the methods. For example:
1327+
// underlying numeric types, the matrix types, and the methods. For example:
13301328

13311329
// >
13321330

@@ -1338,11 +1336,11 @@ BOOST_AUTO_TEST_CASE(test_dynamic_operations) {
13381336
// use_polymorphic_matrices<>::with<add, transpose> YOMM2_GENSYM; // 5
13391337
// ```
13401338

1341-
// 1. all matrix mp_list of `double`, with all operations
1342-
// 2. all matrix mp_list of `int` and `double`, with all operations
1339+
// 1. all matrix types of `double`, with all operations
1340+
// 2. all matrix types of `int` and `double`, with all operations
13431341
// 3. square and symmetric matrices of `double`, with all operations
13441342
// 4. square and symmetric matrices of `int` and `double`, polymorphic addition only
1345-
// 5. all matrix mp_list of `double`, with all operations
1343+
// 5. all matrix types of `double`, with all operations
13461344

13471345
// Let's implement this. First we need a few helpers.
13481346

@@ -1424,17 +1422,17 @@ struct definition_traits<add> : binary_definition_traits<add> {};
14241422

14251423
template<template<typename> typename... Ms>
14261424
struct use_polymorphic_matrices {
1427-
using abstract_matrix_templates = mp_list<
1425+
using abstract_matrix_templates = types<
14281426
typename template_of<typename Ms<double>::abstract_type>::type...>;
14291427
using concrete_matrix_templates = templates<Ms...>;
14301428
template<typename... Ts>
14311429
struct of {
1432-
using numeric_types = mp_list<Ts...>;
1430+
using numeric_types = types<Ts...>;
14331431
template<template<typename...> typename... Ops>
14341432
struct with
14351433
: use_classes<
1436-
apply_product<abstract_matrix_templates, mp_list<Ts...>>,
1437-
apply_product<concrete_matrix_templates, mp_list<Ts...>>>,
1434+
apply_product<abstract_matrix_templates, types<Ts...>>,
1435+
apply_product<concrete_matrix_templates, types<Ts...>>>,
14381436
definition_traits<Ops>::template fn<
14391437
abstract_matrix_templates, concrete_matrix_templates,
14401438
numeric_types>... {};

0 commit comments

Comments
 (0)