Toolbox snapshot
The Reactive C++ Toolbox
Loading...
Searching...
No Matches
Struct.hpp
Go to the documentation of this file.
1// The Reactive C++ Toolbox.
2// Copyright (C) 2013-2019 Swirly Cloud Limited
3// Copyright (C) 2021 Reactive Markets Limited
4//
5// Licensed under the Apache License, Version 2.0 (the "License");
6// you may not use this file except in compliance with the License.
7// You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing, software
12// distributed under the License is distributed on an "AS IS" BASIS,
13// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14// See the License for the specific language governing permissions and
15// limitations under the License.
16
17#ifndef TOOLBOX_UTIL_STRUCT_HPP
18#define TOOLBOX_UTIL_STRUCT_HPP
19
20#include <cstddef>
21
22// The Struct concept is essentially a tag-based tuple that was inspired by:
23// 1. Bronek Kozicki and his open souce projects (https://github.com/Bronek)
24// 2. std::tuple<>
25// 3. http://blogs.microsoft.co.il/sasha/2015/01/12/implementing-tuple-part-1/
26
27namespace toolbox {
28inline namespace util {
29namespace detail {
30
31template <typename TagT, typename ValueT>
32struct Member {
33 constexpr explicit Member(const ValueT& value)
34 : value{value}
35 {
36 }
38};
39
40template <typename...>
41struct Struct;
42
43template <>
44struct Struct<> {
45
46 enum : std::size_t { Size = 0 };
47
48 template <typename TagT, typename ValueT>
49 constexpr auto extend(const ValueT& head) const
50 {
51 return Struct<Member<TagT, ValueT>>{head};
52 }
53
54 constexpr const auto& slice(...) const noexcept { return *this; }
55 constexpr auto& slice(...) noexcept { return *this; }
56};
57
58template <typename TagT, typename ValueT, typename... TagsT, typename... ValuesT>
59struct Struct<Member<TagT, ValueT>, Member<TagsT, ValuesT>...> : Struct<Member<TagsT, ValuesT>...> {
60
62 enum : std::size_t { Size = 1 + Tail::Size };
63
64 constexpr explicit Struct(const ValueT& head)
65 : head{head}
66 {
67 }
68 constexpr Struct(const ValueT& head, const Tail& tail)
69 : Tail{tail}
70 , head{head}
71 {
72 }
73 template <typename TagU, typename ValueU>
74 constexpr auto extend(const ValueU& head) const
75 {
77 Member<TagsT, ValuesT>...>{head, *this};
78 }
79
80 using Tail::slice;
81 constexpr const auto& slice(TagT) const noexcept { return *this; };
82 constexpr auto& slice(TagT) noexcept { return *this; };
83
85};
86
87} // namespace detail
88
89constexpr auto Struct = detail::Struct<>{};
90
91template <typename... TagsT, typename... ValuesT>
92constexpr bool empty(const detail::Struct<detail::Member<TagsT, ValuesT>...>& s)
93{
94 return s.Size == 0;
95}
96
97template <typename... TagsT, typename... ValuesT>
98constexpr std::size_t size(const detail::Struct<detail::Member<TagsT, ValuesT>...>& s)
99{
100 return s.Size;
101}
102
103template <typename TagT, typename... TagsT, typename... ValuesT>
104constexpr bool has(const detail::Struct<detail::Member<TagsT, ValuesT>...>& s, TagT tag = {})
105{
106 return s.slice(tag).Size > 0;
107}
108
109template <typename TagT, typename... TagsT, typename... ValuesT>
110constexpr const auto& get(const detail::Struct<detail::Member<TagsT, ValuesT>...>& s, TagT tag = {})
111{
112 return s.slice(tag).head;
113}
114
115template <typename TagT, typename... TagsT, typename... ValuesT>
116constexpr auto& get(detail::Struct<detail::Member<TagsT, ValuesT>...>& s, TagT tag = {})
117{
118 return s.slice(tag).head;
119}
120
121} // namespace util
122} // namespace toolbox
123
124#endif // TOOLBOX_UTIL_STRUCT_HPP
constexpr bool has(const detail::Struct< detail::Member< TagsT, ValuesT >... > &s, TagT tag={})
Definition Struct.hpp:104
constexpr auto Struct
Definition Struct.hpp:89
constexpr std::size_t size(const detail::Struct< detail::Member< TagsT, ValuesT >... > &s)
Definition Struct.hpp:98
constexpr bool empty(const detail::Struct< detail::Member< TagsT, ValuesT >... > &s)
Definition Struct.hpp:92
constexpr const auto & get(const detail::Struct< detail::Member< TagsT, ValuesT >... > &s, TagT tag={})
Definition Struct.hpp:110
constexpr auto bind() noexcept
Definition Slot.hpp:92
constexpr Member(const ValueT &value)
Definition Struct.hpp:33
constexpr auto extend(const ValueT &head) const
Definition Struct.hpp:49
constexpr const auto & slice(...) const noexcept
Definition Struct.hpp:54
constexpr auto & slice(...) noexcept
Definition Struct.hpp:55