Skip to content

Commit e25447c

Browse files
composition and choice subsume compound
1 parent a49ddb5 commit e25447c

File tree

10 files changed

+75
-55
lines changed

10 files changed

+75
-55
lines changed

README.md

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ struct simply::iface<insertable, Self> {
3131
int main() {
3232
using namespace std::string_literals;
3333

34-
struct affordances : simply::conjunction<insertable, simply::destructible> {};
34+
struct affordances : simply::composes<insertable, simply::destructible> {};
3535

3636
std::vector<simply::dyn<affordances>> values;
3737
values.emplace_back("Hello, world!"s);
@@ -51,11 +51,17 @@ int main() {
5151
5252
### Features
5353
54-
- `dyn` for type erasure of affordances
54+
- `dyn<Affordance, Storage, Dispatch>` for type erasure of affordances
5555
- Concepts:
5656
- `affordance<Affordance>`
57+
- `fundamental_affordance<Affordance>`
58+
- `compound_affordance<Affordance>`
59+
- `composition_affordance<Affordance>`
60+
- `choice_affordance<Affordance>`
5761
- `affords<T, Affordance>`
5862
- Predefined affordances for common use-cases:
63+
- `composes<Affordances...>`
64+
- `chooses<Affordances...>`
5965
- `destructible`
6066
- `move_constructible`
6167
- `copy_constructible`
@@ -69,8 +75,7 @@ int main() {
6975
7076
### Planned Features
7177
72-
- `disjunction` to compose affordances as unions
73-
- `inplace_storage`
78+
- `inplace_storage<Size, Align>`
7479
- `shared_storage`
7580
- `copy_on_write_storage`
7681
- `invocable` affordance template

include/simply/concepts.hpp

Lines changed: 43 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -51,12 +51,21 @@ concept derived_from_specialization_of = requires(Derived *derived) {
5151
template <typename T>
5252
concept compound_affordance =
5353
simply::affordance<T> and
54-
simply::derived_from_specialization_of<T, simply::conjunction>;
54+
std::derived_from<T, simply::compound_affordance_base>;
5555

5656
template <typename T>
5757
concept fundamental_affordance =
58-
simply::affordance<T> and
59-
not simply::derived_from_specialization_of<T, simply::conjunction>;
58+
simply::affordance<T> and not simply::compound_affordance<T>;
59+
60+
template <typename T>
61+
concept composition_affordance =
62+
simply::compound_affordance<T> and
63+
simply::derived_from_specialization_of<T, simply::composes>;
64+
65+
template <typename T>
66+
concept choice_affordance =
67+
simply::compound_affordance<T> and
68+
simply::derived_from_specialization_of<T, simply::chooses>;
6069

6170
template <typename T>
6271
concept member_affordance =
@@ -86,88 +95,88 @@ concept fundamental_destroy_affordance =
8695
template <typename T, typename U>
8796
concept different_from = not std::same_as<T, U>;
8897

89-
template <simply::compound_affordance Compound, typename T>
90-
inline constexpr bool enable_affordance_for<Compound, T> =
98+
template <simply::composition_affordance Composition, typename T>
99+
inline constexpr bool enable_affordance_for<Composition, T> =
91100
simply::enable_affordance_for<
92-
simply::unique_fundamental_affordances_t<Compound>, T>;
101+
simply::unique_fundamental_affordances_t<Composition>, T>;
93102

94103
template <simply::fundamental_affordance... Fundamental, typename T>
95104
inline constexpr bool
96-
enable_affordance_for<simply::conjunction<Fundamental...>, T> =
105+
enable_affordance_for<simply::composes<Fundamental...>, T> =
97106
(... and simply::enable_affordance_for<Fundamental, T>);
98107

99-
template <simply::compound_affordance T, typename Tag>
108+
template <simply::composition_affordance T, typename Tag>
100109
inline constexpr bool enable_affordance_tag<T, Tag> =
101110
simply::enable_affordance_tag<simply::unique_fundamental_affordances_t<T>,
102111
Tag>;
103112

104113
template <simply::fundamental_affordance... Ts, typename Tag>
105-
inline constexpr bool enable_affordance_tag<simply::conjunction<Ts...>, Tag> =
114+
inline constexpr bool enable_affordance_tag<simply::composes<Ts...>, Tag> =
106115
(... or simply::enable_affordance_tag<Ts, Tag>);
107116

108-
template <simply::compound_affordance Compound, typename Tag>
109-
struct fundamental_affordance_type<Compound, Tag>
117+
template <simply::composition_affordance Composition, typename Tag>
118+
struct fundamental_affordance_type<Composition, Tag>
110119
: simply::fundamental_affordance_type<
111-
simply::unique_fundamental_affordances_t<Compound>, Tag> {};
120+
simply::unique_fundamental_affordances_t<Composition>, Tag> {};
112121

113122
template <simply::fundamental_affordance... Fundamental, typename Tag>
114-
struct fundamental_affordance_type<simply::conjunction<Fundamental...>, Tag>
123+
struct fundamental_affordance_type<simply::composes<Fundamental...>, Tag>
115124
: simply::fundamental_affordance_type<Fundamental, Tag>... {};
116125

117126
template <simply::fundamental_affordance Affordance, typename Tag>
118127
requires simply::enable_affordance_tag<Affordance, Tag>
119128
struct fundamental_affordance_type<Affordance, Tag>
120129
: std::type_identity<Affordance> {};
121130

122-
// terminate on outer affordances<>
131+
// terminate on outer composes<>
123132
template <typename Unique>
124-
struct unique_fundamental_affordances<simply::conjunction<>, Unique>
133+
struct unique_fundamental_affordances<simply::composes<>, Unique>
125134
: std::type_identity<Unique> {};
126135

127-
// handle outer Fundamental as affordances<Fundamental>
136+
// handle outer Fundamental as composes<Fundamental>
128137
template <simply::fundamental_affordance Fundamental, typename Unique>
129138
struct unique_fundamental_affordances<Fundamental, Unique>
130-
: simply::unique_fundamental_affordances<simply::conjunction<Fundamental>,
139+
: simply::unique_fundamental_affordances<simply::composes<Fundamental>,
131140
Unique> {};
132141

133-
// handle outer Compound as affordances<...>
134-
template <simply::compound_affordance Compound, typename Unique>
135-
struct unique_fundamental_affordances<Compound, Unique>
142+
// handle outer Composition as composes<...>
143+
template <simply::composition_affordance Composition, typename Unique>
144+
struct unique_fundamental_affordances<Composition, Unique>
136145
: simply::unique_fundamental_affordances<
137-
simply::base_conjunction_t<Compound>, Unique> {};
146+
simply::base_composition_t<Composition>, Unique> {};
138147

139148
// add inner Fundamental if different from all Unique
140149
template <simply::fundamental_affordance Fundamental, typename... Rest,
141150
simply::different_from<Fundamental>... Unique>
142-
struct unique_fundamental_affordances<simply::conjunction<Fundamental, Rest...>,
143-
simply::conjunction<Unique...>>
151+
struct unique_fundamental_affordances<simply::composes<Fundamental, Rest...>,
152+
simply::composes<Unique...>>
144153
: simply::unique_fundamental_affordances<
145-
simply::conjunction<Rest...>,
146-
simply::conjunction<Unique..., Fundamental>> {};
154+
simply::composes<Rest...>, simply::composes<Unique..., Fundamental>> {
155+
};
147156

148157
// drop inner Fundamental otherwise
149158
template <simply::fundamental_affordance Fundamental, typename... Rest,
150159
typename Unique>
151-
struct unique_fundamental_affordances<simply::conjunction<Fundamental, Rest...>,
160+
struct unique_fundamental_affordances<simply::composes<Fundamental, Rest...>,
152161
Unique>
153-
: simply::unique_fundamental_affordances<simply::conjunction<Rest...>,
162+
: simply::unique_fundamental_affordances<simply::composes<Rest...>,
154163
Unique> {};
155164

156-
// handle inner Compound as affordances<...>
157-
template <simply::compound_affordance Compound, typename... Rest,
165+
// handle inner Composition as composes<...>
166+
template <simply::composition_affordance Composition, typename... Rest,
158167
typename Unique>
159-
struct unique_fundamental_affordances<simply::conjunction<Compound, Rest...>,
168+
struct unique_fundamental_affordances<simply::composes<Composition, Rest...>,
160169
Unique>
161170
: simply::unique_fundamental_affordances<
162-
simply::conjunction<simply::base_conjunction_t<Compound>, Rest...>,
171+
simply::composes<simply::base_composition_t<Composition>, Rest...>,
163172
Unique> {};
164173

165-
// handle inner affordances<First...> as First...
174+
// handle inner composes<First...> as First...
166175
template <typename... First, typename... Rest, typename Unique>
167176
struct unique_fundamental_affordances<
168-
simply::conjunction<simply::conjunction<First...>, Rest...>, Unique>
177+
simply::composes<simply::composes<First...>, Rest...>, Unique>
169178
: simply::unique_fundamental_affordances<
170-
simply::conjunction<First..., Rest...>, Unique> {};
179+
simply::composes<First..., Rest...>, Unique> {};
171180

172181
} // namespace simply
173182

include/simply/copyable.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ struct copy_constructible : simply::copy_affordance_base {
1515
};
1616

1717
struct copyable
18-
: simply::conjunction<simply::copy_constructible, simply::movable> {};
18+
: simply::composes<simply::copy_constructible, simply::movable> {};
1919

2020
} // namespace simply
2121

include/simply/dyn.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,12 +109,14 @@ struct impl<Affordance, Dyn, R(Self, Args...) noexcept(NoExcept)> {
109109
}
110110
};
111111

112+
// TODO refactor impl specializations below to not assume allocator_storage
112113
template <typename Dyn>
113114
concept _allocator_storage_dyn =
114115
simply::specialization_of<Dyn, simply::dyn> and
115116
simply::specialization_of<typename Dyn::storage_type,
116117
simply::allocator_storage>;
117118

119+
// TODO resolve storage type from choices by checking each compatibility with T
118120
template <typename T, typename Dyn>
119121
inline constexpr const auto &_storage_fn =
120122
simply::fn<typename Dyn::storage_type, T>;

include/simply/iface.hpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@ namespace simply {
88
template <simply::affordance Affordance, typename Self>
99
struct iface {};
1010

11-
template <simply::compound_affordance Affordance, typename Self>
11+
template <simply::composition_affordance Affordance, typename Self>
1212
struct iface<Affordance, Self>
1313
: simply::iface<simply::unique_fundamental_affordances_t<Affordance>,
1414
Self> {};
1515

1616
template <simply::fundamental_affordance... Affordances, typename Self>
17-
struct iface<simply::conjunction<Affordances...>, Self>
17+
struct iface<simply::composes<Affordances...>, Self>
1818
: simply::iface<Affordances, Self>... {};
1919

2020
} // namespace simply

include/simply/movable.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ struct move_constructible : simply::move_affordance_base {
1414
};
1515

1616
struct movable
17-
: simply::conjunction<simply::move_constructible, simply::destructible> {};
17+
: simply::composes<simply::move_constructible, simply::destructible> {};
1818

1919
} // namespace simply
2020

include/simply/type_traits.hpp

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ namespace simply {
88

99
struct affordance_base {};
1010

11+
struct compound_affordance_base : simply::affordance_base {};
12+
1113
struct member_affordance_base : simply::affordance_base {};
1214

1315
struct constructor_affordance_base : simply::member_affordance_base {};
@@ -48,7 +50,10 @@ using destroy_affordance_t =
4850
simply::destroy_affordance_base>;
4951

5052
template <typename... Ts>
51-
struct conjunction : simply::affordance_base {};
53+
struct composes : simply::compound_affordance_base {};
54+
55+
template <typename... Ts>
56+
struct chooses : simply::compound_affordance_base {};
5257

5358
template <typename, template <typename...> typename>
5459
inline constexpr bool is_specialization_of_v = false;
@@ -64,21 +69,22 @@ using base_specialization_of_t = decltype(simply::_as_specialization_of<Base>(
6469
static_cast<Derived *>(nullptr)));
6570

6671
template <typename T>
67-
using base_conjunction_t =
68-
simply::base_specialization_of_t<T, simply::conjunction>;
72+
using base_composition_t =
73+
simply::base_specialization_of_t<T, simply::composes>;
6974

7075
template <typename T>
7176
inline constexpr bool enable_affordance =
7277
std::derived_from<T, simply::affordance_base>;
7378

79+
// TODO integrate this customization point with impl and/or affordance_traits
7480
template <typename Affordance, typename T>
7581
inline constexpr bool enable_affordance_for =
7682
requires { &Affordance::template fn<T>; };
7783

7884
template <typename T, typename Tag>
7985
inline constexpr bool enable_affordance_tag = std::derived_from<T, Tag>;
8086

81-
template <typename Affordance, typename Unique = simply::conjunction<>>
87+
template <typename Affordance, typename Unique = simply::composes<>>
8288
struct unique_fundamental_affordances;
8389

8490
template <typename Affordance>

include/simply/vtable.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ struct vtable
1111
Self> {};
1212

1313
template <simply::fundamental_affordance... Affordances, typename Self>
14-
struct vtable<simply::conjunction<Affordances...>, Self>
14+
struct vtable<simply::composes<Affordances...>, Self>
1515
: simply::vtable<Affordances, Self>... {};
1616

1717
template <simply::fundamental_affordance Affordance, typename Self>
@@ -30,8 +30,8 @@ inline constexpr simply::vtable<Affordance, Self> vtable_for = {
3030

3131
template <simply::fundamental_affordance... Affordances, typename Self,
3232
typename T>
33-
inline constexpr simply::vtable<simply::conjunction<Affordances...>, Self>
34-
vtable_for<simply::conjunction<Affordances...>, Self, T> = {
33+
inline constexpr simply::vtable<simply::composes<Affordances...>, Self>
34+
vtable_for<simply::composes<Affordances...>, Self, T> = {
3535
simply::vtable_for<Affordances, Self, T>...,
3636
};
3737

tests/counters.cpp

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,11 +59,9 @@ struct simply::iface<labeled<LabelT>, Self> {
5959

6060
// test dyn<countable> at compile-time
6161
static_assert([] {
62-
// compose the affordances into a compound affordance
6362
struct countable
64-
: simply::conjunction<copy_countable<int>, labeled<char>,
65-
simply::copy_constructible, simply::destructible> {
66-
};
63+
: simply::composes<copy_countable<int>, labeled<char>,
64+
simply::copy_constructible, simply::destructible> {};
6765

6866
using dyn = simply::dyn<countable>;
6967
static_assert(requires {

tests/stream.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
TEST(Stream, TypeErasedInsertion) {
1010
using namespace std::string_literals;
1111

12-
struct affordances : simply::conjunction<simply::insertable<std::ostream>,
13-
simply::destructible> {};
12+
struct affordances : simply::composes<simply::insertable<std::ostream>,
13+
simply::destructible> {};
1414

1515
std::vector<simply::dyn<affordances>> values;
1616
values.emplace_back("Hello, world!"s);

0 commit comments

Comments
 (0)