Skip to content

Commit ab45f4f

Browse files
authored
Merge pull request #405 from elbeno/extra-design-docs
📝 Add more design thoughts
2 parents 42e68fc + a046ee2 commit ab45f4f

3 files changed

Lines changed: 116 additions & 37 deletions

File tree

docs/design/tuple.md

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,44 @@ the resulting pairs to pull the elements from each input tuple.
1616

1717
`stdx::tuple` is a basic dependency for many things; for that reason `tuple.hpp`
1818
doesn't include very much, and in particular must avoid circular dependencies.
19+
1920
For example, it can't use formatted `static_assert`s (because they make use of
20-
`tuple`).
21+
`tuple`). The diagnostics emitted when `get` fails to compile are helped by
22+
suitable type names in the `stdx::error` namespace:
23+
24+
```cpp
25+
static_assert(always_false_v<looking_for<type>, in_tuple<Ts...>>,
26+
"Type not found in tuple!");
27+
```
28+
29+
## Constructors
30+
31+
There are a couple of basic ways of implementing tuple. The standard uses
32+
recursion like this (sketch):
33+
34+
```
35+
struct tuple<T, Ts...> : tuple<Ts...> {
36+
T element;
37+
};
38+
```
39+
40+
This means that the actual layout of the elements is "in reverse", because the
41+
first element is in the `struct` that inherits from all the rest, etc. This also
42+
means that `std::tuple` has many complex constructors.
43+
44+
`stdx::tuple` uses the other way: tag each type with an index (this is necessary
45+
for uniqueness, so that we can have repeated types in the tuple) and inherit
46+
from the expanded pack of such elements.
47+
48+
This means the layout is in order, and the rule of zero can apply. To ease the
49+
construction, we turn off `-Wmissing-braces` so that we can write:
50+
51+
```cpp
52+
auto t = stdx::tuple{1, 2, 3};
53+
```
54+
55+
and the compiler doesn't complain about brace elision (otherwise it would want
56+
us to write e.g. `stdx::tuple{{1}, {2}, {3}}`).
2157
2258
## `tuplelike` vs `has_tuple_protocol`
2359

docs/design/type_traits.md

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,3 +19,45 @@ operations are done through alias templates, which are much cheaper.
1919
STL implementations typically do the same thing for internal use, but the
2020
standard constrains them to provide the more expensive interface.
2121

22+
## `to_underlying`
23+
24+
In the standard, `underlying_type_t` is in `<type_traits>` while `to_underlying`
25+
is in `<utility>`. `stdx` puts both in `<type_traits>`.
26+
27+
In the standard, this fails to compile:
28+
29+
```cpp
30+
auto x = to_underlying(42);
31+
```
32+
33+
because `to_underlying` is defined only on enumeration types. But in practice,
34+
it is very useful in generic code to have an "idempotent" form of
35+
`to_underlying` that reduces an enumeration to the underlying integral type and
36+
is a no-op otherwise. That's what `stdx::to_underlying` does.
37+
38+
### Other ideas
39+
40+
`stdx::to_underlying` could be constrained to work on either integral or
41+
enumeration types, but it is currently unconstrained.
42+
43+
## Tuple helpers
44+
45+
The standard seems ambiguous on where the primary template declarations for
46+
`tuple_element` and `tuple_size` are to be kept, or if it matters. We choose to
47+
put them in `<type_traits.hpp>`. Each class that specializes them then includes
48+
`<type_traits.hpp>` rather than `<tuple.hpp>`.
49+
50+
## `type_identity`
51+
52+
`std::type_identity` and `std::type_identity_t` exist from C++20, so in theory
53+
we could get rid of their counterparts in `stdx`. However, the standard does not
54+
define `type_identity_v` -- which is actually very useful. Given that utility,
55+
it is consistent to provide all three in `stdx`; especially given that they are
56+
trivial.
57+
58+
## Miscellaneous
59+
60+
We expect to remove several type traits from `stdx` as standard adoption allows.
61+
62+
`is_specialization_of` and `is_same_template_v` get a lot easier particularly
63+
with reflection.

docs/header_graph.mmd

Lines changed: 37 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ flowchart BT
66
array(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/array.hpp">array.hpp</a>)
77
atomic(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/atomic.hpp">atomic.hpp</a>)
88
ct_conversions(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/ct_conversions.hpp">ct_conversions.hpp</a>)
9+
priority(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/priority.hpp">priority.hpp</a>)
10+
numeric(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/numeric.hpp">numeric.hpp</a>)
911
array ~~~ compiler
1012
atomic ~~~ compiler
1113
ct_conversions --> compiler
12-
priority(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/priority.hpp">priority.hpp</a>)
13-
numeric(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/numeric.hpp">numeric.hpp</a>)
1414
priority ~~~ compiler
1515
numeric ~~~ compiler
1616

@@ -20,85 +20,86 @@ flowchart BT
2020

2121
%% level 3
2222
iterator(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/iterator.hpp">iterator.hpp</a>)
23-
iterator --> type_traits
2423
concepts(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/concepts.hpp">concepts.hpp</a>)
25-
concepts --> type_traits
2624
udls(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/udls.hpp">udls.hpp</a>)
2725
function_traits(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/function_traits.hpp">function_traits.hpp</a>)
26+
iterator --> type_traits
27+
concepts --> type_traits
2828
function_traits --> type_traits
2929

3030
%% level 4
3131
cx_vector(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/cx_vector.hpp">cx_vector.hpp</a>)
32+
rollover(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/rollover.hpp">rollover.hpp</a>)
33+
utility(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/utility.hpp">utility.hpp</a>)
3234
cx_vector --> iterator
3335
cx_vector --> concepts
34-
rollover(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/rollover.hpp">rollover.hpp</a>)
3536
rollover --> concepts
36-
utility(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/utility.hpp">utility.hpp</a>)
3737
utility --> concepts
3838
utility --> udls
3939

4040
%% level 5
4141
cx_map(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/cx_map.hpp">cx_map.hpp</a>)
42+
bit(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/bit.hpp">bit.hpp</a>)
43+
ct_string(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/ct_string.hpp">ct_string.hpp</a>)
44+
tuple(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/tuple.hpp">tuple.hpp</a>)
4245
cx_map ---> iterator
4346
cx_map --> utility
44-
bit(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/bit.hpp">bit.hpp</a>)
4547
bit --> utility
46-
ct_string(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/ct_string.hpp">ct_string.hpp</a>)
4748
ct_string --> utility
48-
tuple(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/tuple.hpp">tuple.hpp</a>)
4949
tuple --> utility
5050

5151
%% level 6
5252
span(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/span.hpp">span.hpp</a>)
53+
byterator(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/byterator.hpp">byterator.hpp</a>)
54+
cx_set(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/cx_set.hpp">cx_set.hpp</a>)
55+
bitset(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/bitset.hpp">bitset.hpp</a>)
56+
panic(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/panic.hpp">panic.hpp</a>)
57+
env(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/env.hpp">env.hpp</a>)
58+
functional(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/functional.hpp">functional.hpp</a>)
59+
C(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/algorithm.hpp">algorithm.hpp</a><br><a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/tuple_destructure.hpp">tuple_destructure.hpp</a>)
60+
for_each_n_args(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/for_each_n_args.hpp">for_each_n_args.hpp</a>)
61+
62+
%% level 7
63+
cx_multimap(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/cx_multimap.hpp">cx_multimap.hpp</a>)
64+
cx_queue(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/cx_queue.hpp">cx_queue.hpp</a>)
65+
atomic_bitset(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/atomic_bitset.hpp">atomic_bitset.hpp</a>)
66+
B(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/intrusive_forward_list.hpp">intrusive_forward_list.hpp<br><a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/intrusive_list.hpp">intrusive_list.hpp</a>)
67+
pp_map(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/pp_map.hpp">pp_map.hpp</a>)
68+
ranges(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/ranges.hpp">ranges.hpp</a>)
69+
tuple_algorithms(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/tuple_algorithms.hpp">tuple_algorithms.hpp</a>)
70+
ct_format(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/ct_format.hpp">ct_format.hpp</a>)
71+
call_by_need(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/call_by_need.hpp">call_by_need.hpp</a>)
72+
latched(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/latched.hpp">latched.hpp</a>)
73+
optional(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/optional.hpp">optional.hpp</a>)
74+
75+
%% level 8
76+
cached(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/cached.hpp">cached.hpp</a>)
77+
static_assert(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/static_assert.hpp">static_assert.hpp</a>)
78+
5379
span ----> iterator
5480
span --> bit
55-
byterator(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/byterator.hpp">byterator.hpp</a>)
5681
byterator --> bit
57-
cx_set(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/cx_set.hpp">cx_set.hpp</a>)
5882
cx_set ---> cx_map
59-
bitset(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/bitset.hpp">bitset.hpp</a>)
6083
bitset --> bit
6184
bitset --> ct_string
62-
panic(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/panic.hpp">panic.hpp</a>)
6385
panic --> ct_string
64-
env(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/env.hpp">env.hpp</a>)
6586
env --> ct_string
66-
tuple_algorithms(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/tuple_algorithms.hpp">tuple_algorithms.hpp</a>)
6787
tuple_algorithms --> tuple
68-
functional(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/functional.hpp">functional.hpp</a>)
6988
functional --> tuple
70-
C(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/algorithm.hpp">algorithm.hpp</a><br><a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/tuple_destructure.hpp">tuple_destructure.hpp</a>)
7189
C --> tuple
72-
for_each_n_args(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/for_each_n_args.hpp">for_each_n_args.hpp</a>)
7390
for_each_n_args ----> function_traits
7491
for_each_n_args --> tuple
75-
76-
%% level 7
77-
cx_multimap(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/cx_multimap.hpp">cx_multimap.hpp</a>)
7892
cx_multimap --> cx_set
79-
cx_queue(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/cx_queue.hpp">cx_queue.hpp</a>)
8093
cx_queue ----> iterator
8194
cx_queue --> panic
82-
atomic_bitset(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/atomic_bitset.hpp">atomic_bitset.hpp</a>)
8395
atomic_bitset ---> bitset
84-
B(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/intrusive_forward_list.hpp">intrusive_forward_list.hpp<br><a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/intrusive_list.hpp">intrusive_list.hpp</a>)
8596
B --> panic
86-
pp_map(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/pp_map.hpp">pp_map.hpp</a>)
87-
ranges(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/ranges.hpp">ranges.hpp</a>)
88-
call_by_need(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/call_by_need.hpp">call_by_need.hpp</a>)
89-
call_by_need --> tuple_algorithms
90-
ct_format(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/ct_format.hpp">ct_format.hpp</a>)
9197
ct_format ---> ct_string
92-
ct_format --> tuple_algorithms
9398
ct_format --> pp_map
9499
ct_format --> ranges
95-
latched(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/latched.hpp">latched.hpp</a>)
100+
ct_format --> tuple_algorithms
101+
call_by_need --> tuple_algorithms
96102
latched --> functional
97-
optional(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/optional.hpp">optional.hpp</a>)
98103
optional --> functional
99-
100-
%% level 8
101-
cached(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/cached.hpp">cached.hpp</a>)
102104
cached --> latched
103-
static_assert(<a href="https://github.com/intel/cpp-std-extensions/tree/main/include/stdx/static_assert.hpp">static_assert.hpp</a>)
104105
static_assert --> ct_format

0 commit comments

Comments
 (0)