Algorithms Library Toolkit
A toolkit for algorithms, especially for algorithms on formal languages
variant.hpp
Go to the documentation of this file.
1
28#pragma once
29
30#include <variant>
31#include <compare>
32
33#include <ext/ostream>
34
38
39namespace ext {
40
41template < class Visitor, class... Variants >
42constexpr auto visit ( Visitor && vis, Variants && ... vars ) {
43 return std::visit ( std::forward < Visitor > ( vis ), std::forward < Variants > ( vars ).asStdVariant ( ) ... );
44}
45
53template < class Res, class ... Ts >
55};
56
64template < class ... ResTs >
65struct variant_builder_impl < std::variant < ResTs ... > > {
66 typedef std::variant < ResTs ... > std_variant;
67
68 template < class T >
69 using index_in = ext::index_in < T, ResTs ... >;
70};
71
80template < class ... ResTs, class T, class ... Ts >
81struct variant_builder_impl < std::variant < ResTs ... >, T, Ts ... > : public variant_builder_impl < typename std::conditional < is_in < T, ResTs ... >::value, std::variant < ResTs ... >, std::variant < ResTs ..., T > >::type, Ts ... > {
82};
83
84template < class T, class ... Ts >
85struct variant_builder_start : public variant_builder_impl < std::variant < T >, Ts ... > {
86};
87
88template < class ... Ts >
90
97template < typename ... Ts >
98class variant : public std_variant < Ts ... > {
99
100 template < class Visitor, class... Variants >
101 friend constexpr auto visit ( Visitor && vis, Variants && ... vars );
102
106 class VariantToStream {
110 ext::ostream & m_out;
111 public:
117 explicit VariantToStream ( ext::ostream & out ) : m_out ( out ) {
118 }
119
127 template < class T >
128 void operator ( ) ( const T & value ) {
129 m_out << value;
130 }
131 };
132
136 typedef std_variant < Ts ... > base;
137
138 const base & asStdVariant ( ) const & {
139 return * this;
140 }
141
142 base & asStdVariant ( ) & {
143 return * this;
144 }
145
146 base && asStdVariant ( ) && {
147 return std::move ( * this );
148 }
149
150public:
154 using std_variant < Ts ... >::std_variant; // NOLINT(modernize-use-equals-default)
155
159 using std_variant < Ts ... >::operator=;
160#ifndef __clang__
161
165 variant ( ) = default;
166
170 variant ( const variant & other ) = default;
171
175 variant ( variant && other ) = default;
176
180 variant & operator = ( variant && other ) = default;
181
185 variant & operator = ( const variant & other ) = default;
186#endif
187
196 template < typename T >
197 bool is() const {
198 return std::holds_alternative < T > ( * this );
199 }
200
209 template < typename T >
210 requires ( ext::Included < std::decay_t < T >, Ts ... > )
211 void set ( T && value ) {
212 * this = std::forward < T > ( value );
213 }
214
225 template < typename T >
226 T & get ( ) & {
227 return std::get < T > ( * this );
228 }
229
240 template<typename T >
241 const T & get ( ) const & {
242 return std::get < T > ( * this );
243 }
244
255 template < typename T >
256 T && get ( ) && {
257 return std::move ( std::get < T > ( * this ) );
258 }
259
271 template < class Result, class Callable >
272 Result call ( Callable callable ) const {
273 return ext::visit ( callable, * this );
274 }
275
286 obj.call < void > ( VariantToStream ( out ) );
287 return out;
288 }
289
290 template < ext::Included < Ts ... > T >
291 auto operator <=> ( const T & other ) const {
292 auto indexRes = this->index ( ) <=> variant_builder_start < Ts ... >::template index_in < T >::value;
293 if ( indexRes != 0 )
294 return indexRes;
295
296 return this->template get < T > ( ) <=> other;
297 }
298
299 template < ext::Included < Ts ... > T >
300 bool operator == ( const T & other ) const {
301 auto indexRes = this->index ( ) == variant_builder_start < Ts ... >::template index_in < T >::value;
302 if ( ! indexRes )
303 return indexRes;
304
305 return this->template get < T > ( ) == other;
306 }
307};
308
309} /* namespace ext */
310
311namespace std {
312
313template < class ... Types >
314struct variant_size < ext::variant < Types ... > > : public variant_size < typename ext::variant < Types ... >::std_variant > { };
315
316template < size_t Np, typename ... Types >
317struct variant_alternative < Np, ext::variant < Types ... > > {
318 using type = variant_alternative_t < Np, typename ext::variant < Types ... >::std_variant >;
319};
320
321}
322
Definition: ostream.h:14
Definition: set.hpp:44
Implementation of the variant class allowing to store any type of those listed in the template parame...
Definition: variant.hpp:98
auto operator<=>(const T &other) const
Definition: variant.hpp:291
variant()=default
variant(variant &&other)=default
variant & operator=(variant &&other)=default
Result call(Callable callable) const
Callback executor on current variant value.
Definition: variant.hpp:272
bool is() const
Function to test whether the variant currently contains type T.
Definition: variant.hpp:197
T & get() &
Allows to retrieve a value from the variant.
Definition: variant.hpp:226
const T & get() const &
Allows to retrieve a value from the variant.
Definition: variant.hpp:241
bool operator==(const T &other) const
Definition: variant.hpp:300
constexpr friend auto visit(Visitor &&vis, Variants &&... vars)
Definition: variant.hpp:42
variant(const variant &other)=default
friend ext::ostream & operator<<(ext::ostream &out, const variant< Ts ... > &obj)
Operator to print the variant to the output stream.
Definition: variant.hpp:285
T && get() &&
Allows to retrieve a value from the variant.
Definition: variant.hpp:256
Concept to test whether type T is in a types pack. The trait provides field value set to true if the ...
Definition: concepts.hpp:40
Definition: sigHandler.cpp:20
typename variant_builder_start< Ts ... >::std_variant std_variant
Definition: variant.hpp:89
constexpr auto visit(Visitor &&vis, Variants &&... vars)
Definition: variant.hpp:42
Definition: FordFulkerson.hpp:16
Trait to get index of type T is in a types pack. The trait provides field value set to an integral va...
Definition: type_traits.hpp:111
std::variant< ResTs ... > std_variant
Definition: variant.hpp:66
Class to help building of the variant type or, in case variant is requested to be constructed from si...
Definition: variant.hpp:54
Definition: variant.hpp:85
variant_alternative_t< Np, typename ext::variant< Types ... >::std_variant > type
Definition: variant.hpp:318