Algorithms Library Toolkit
A toolkit for algorithms, especially for algorithms on formal languages
ValueHolder.hpp
Go to the documentation of this file.
1
6#pragma once
7
8#include <optional>
9
10#include <ext/memory>
11#include <ext/typeindex>
12#include <ext/typeinfo>
14
15namespace abstraction {
16
17template < class Type >
18class ValueImpl : public ValueHolderInterface < std::decay_t < Type > > {
19 std::optional < std::decay_t < Type > > m_data;
20
21public:
23
24 void setValue ( const Type & data ) override {
25 m_data = std::move ( const_cast < Type && > ( data ) );
26 }
27
28 Type && getValue ( ) override {
29 return std::move ( m_data.value ( ) );
30 }
31};
32
33template < class Type >
34class ReferenceImpl : public ValueHolderInterface < Type > {
35 std::optional < std::reference_wrapper < Type > > m_data;
36
37public:
39
40 void setValue ( const Type & data ) override {
41 m_data = std::reference_wrapper < Type > ( const_cast < Type & > ( data ) );
42 }
43
44 Type && getValue ( ) override {
45 return std::move ( m_data->get ( ) );
46 }
47};
48
49template < class Type >
50class ValueHolder : public std::conditional_t < std::is_reference_v < Type >, ReferenceImpl < std::decay_t < Type > >, ValueImpl < std::decay_t < Type > > > {
51 bool m_isTemporary;
52
53 abstraction::TypeQualifiers::TypeQualifierSet getTypeQualifiers ( ) const override {
54 return abstraction::TypeQualifiers::typeQualifiers < Type > ( );
55 }
56
57 ext::type_index getTypeIndex ( ) const override {
58 return ext::type_index ( typeid ( std::decay_t < Type > ) );
59 }
60
61 bool isTemporary ( ) const override {
62 return m_isTemporary;
63 }
64
65 std::shared_ptr < abstraction::Value > asValue ( bool move, bool temporary ) override {
66 ( void ) move;
67 ( void ) temporary;
68
69 if constexpr ( std::is_abstract_v < std::decay_t < Type > > )
70 throw std::domain_error ( "Cannot declare value of abstract class." );
71 else if constexpr ( ! std::is_assignable_v < std::decay_t < Type > &, std::decay_t < Type > > )
72 throw std::domain_error ( "Cannot assign value." );
73 else
74 return std::make_shared < abstraction::ValueHolder < std::decay_t < Type > > > ( retrieveValue < std::decay_t < Type > > ( this->shared_from_this ( ), move ), temporary );
75 }
76
77public:
78 ValueHolder ( Type && value, bool temporary ) : m_isTemporary ( temporary ) {
79 if ( TypeQualifiers::isLvalueRef ( abstraction::TypeQualifiers::typeQualifiers < Type > ( ) ) && this->isTemporary ( ) )
80 throw std::domain_error ( "Lvalue references cannot be temporaries." );
81
82 this->setValue ( std::forward < Type > ( value ) );
83 }
84};
85
86} /* namespace abstraction */
87
Definition: ValueHolder.hpp:34
void setValue(const Type &data) override
Definition: ValueHolder.hpp:40
Type && getValue() override
Definition: ValueHolder.hpp:44
TypeQualifierSet
Definition: TypeQualifiers.hpp:15
static constexpr bool isLvalueRef(TypeQualifierSet arg)
Definition: TypeQualifiers.hpp:47
Definition: ValueHolderInterface.hpp:15
Definition: ValueHolder.hpp:50
ValueHolder(Type &&value, bool temporary)
Definition: ValueHolder.hpp:78
Definition: ValueHolder.hpp:18
void setValue(const Type &data) override
Definition: ValueHolder.hpp:24
Type && getValue() override
Definition: ValueHolder.hpp:28
Definition: typeindex.h:37
Definition: AlgorithmAbstraction.hpp:11
Type
Definition: MeasurementTypes.hpp:20