Loading...
Searching...
No Matches
attribute.h
Go to the documentation of this file.
1#ifndef _BBM_ATTRIBUTE_H_
2#define _BBM_ATTRIBUTE_H_
3
4#include <type_traits>
5
8
10
11#include "core/stringconvert.h"
12
13
14/***********************************************************************/
15/*! \file attribute.h
16
17 \brief A warpper class to attach a properties to a class via a
18 property struct. The propert expects by default at least
19 a type.
20
21************************************************************************/
22
23namespace bbm {
24
25 //! \brief Base declaration of attribute; further specialized below.
26 template<typename CONF> struct attribute;
27
28 /**********************************************************************/
29 /*! \brief Attributes for non-scalars (leverage inheritance)
30
31 \tparam PROP = attribute property
32
33 Implements: concepts::attribute
34
35 ***********************************************************************/
36 template<typename PROP> requires (concepts::attribute_property<PROP> && !std::is_scalar_v<typename PROP::type>)
37 struct attribute<PROP> : public PROP::type
38 {
39 using type = typename PROP::type;
40 using prop = PROP;
41
42 //! \brief Default construstor
43 inline attribute(void) = default;
44
45 //! \brief Copy Constructor
46 template<typename T> requires concepts::attribute<T>
47 inline attribute(const T& t)
48 {
49 if constexpr (concepts::convertible<attribute, T>) convert(*this, t); // call user-defined conversion
50 else value() = t;
51 }
52
53 //! \brief Forward constructor
54 template<typename... U> requires ((sizeof...(U) != 1) || (!concepts::attribute<U> && ...)) && requires(U&&... u) {{ type(std::forward<U>(u)...)};}
55 inline attribute(U&&... u) : type(std::forward<U>(u)...) {}
56
57 //! @{ \name Cast operators
58 template<typename TYPE> requires std::constructible_from<TYPE, type>
59 explicit inline operator TYPE(void) const { return TYPE(type(*this)); }
60
61 inline operator type&(void) { return *this; }
62 inline operator const type&(void) const { return *this; }
63
64 inline type& value(void) { return *this; }
65 inline const type& value(void) const { return *this; }
66 //! @}
67
68 //! \brief Assignment operator
69 template<typename T> attribute& operator=(const T& t) { value() = attribute(t).value(); return *this; }
70
71 //! @{ \name Operator forwarding
72 inline decltype(auto) operator->(void) { return type::operator->(); }
73 inline decltype(auto) operator->(void) const { return type::operator->(); }
74
75 template<typename S> inline decltype(auto) operator->*(S s) { return type::operator->*(s); }
76 template<typename S> inline decltype(auto) operator->*(S s) const { return type::operator->*(s); }
77 //! @}
78
79 //! \brief Custom toString
80 inline std::string toString(void) const { return bbm::toString(value()); }
81
82 //! \brief Custom fromString
83 static inline attribute fromString(const std::string& str) { return attribute( bbm::fromString<type>(str) ); }
84 };
85
86
87 /**********************************************************************/
88 /*! \brief Attribute specialization for scalar types for which we
89 cannot use inheritance.
90
91 \tparam PROP = attribute property
92
93 Implements: concepts::attribute
94
95 ***********************************************************************/
96 template<typename PROP> requires (concepts::attribute_property<PROP> && std::is_scalar_v<typename PROP::type>)
97 struct attribute<PROP>
98 {
99 using type = typename PROP::type;
100 using prop = PROP;
101
102 //! \brief Default construstor
103 inline attribute(void) = default;
104
105 //! \brief Value constructor
106 inline attribute(const type& t) { _value = t; }
107
108 //! \brief Copy Constructor
109 template<typename T> requires concepts::attribute<T>
110 inline attribute(const T& t)
111 {
112 if constexpr (concepts::convertible<attribute, T>) convert(*this, t);
113 else value() = t;
114 }
115
116 //! @{ \name Cast operators
117 template<typename TYPE> requires std::constructible_from<TYPE,type>
118 explicit inline operator TYPE(void) const { return TYPE(_value); }
119
120 inline operator type&(void) { return _value; }
121 inline operator const type&(void) const { return _value; }
122
123 inline type& value(void) { return _value; }
124 inline const type& value(void) const { return _value; }
125 //! @}
126
127 //! \brief Assignment operator
128 template<typename T> attribute& operator=(const T& t) { value() = attribute(t).value(); return *this; }
129
130 //! @{ \name Forward pointer operators
131 inline decltype(auto) operator->(void) { return _value; }
132 inline decltype(auto) operator->(void) const { return _value; }
133
134 template<typename S> inline decltype(auto) operator->*(S s) { return _value->*(s); }
135 template<typename S> inline decltype(auto) operator->*(S s) const { return _value->*(s); }
136 //! @}
137
138 //! \brief Custom toString
139 inline std::string toString(void) const { return bbm::toString(value()); }
140
141 //! \brief Custom fromString
142 static inline attribute fromString(const std::string& str) { return attribute( bbm::fromString<type>(str) ); }
143
144 private:
146 };
147
148 /**********************************************************************/
149 /*! @{ \name Friend operators with attributes
150
151 \brief Handle the case of 'scalar OP attribute' by explicitely casting
152 attribute to its value.
153
154 **********************************************************************/
155#define BBM_ATTR_POST(OP) template<typename U, typename P> requires std::is_scalar_v<U> inline constexpr auto operator OP (U&& u, const attribute<P>& a) { return (std::forward<U>(u) OP a.value()); }
156
162
166 BBM_ATTR_POST(&&)
167 BBM_ATTR_POST(||)
168
170 BBM_ATTR_POST(<=)
172 BBM_ATTR_POST(>=)
173 BBM_ATTR_POST(==)
174 BBM_ATTR_POST(!=)
175
176 #undef BBM_ATTR_POST
177 //! @}
178
179} // end bbm namespace
180
181
182
183#endif /* _BBM_ATTRIBUTE_H_ */
Helper methods for extracting the value of an attribute (according to concepts::attribute).
attribute_property concept
Definition: attribute.h:22
attribute concept
Definition: attribute.h:39
convertible concept
Definition: convertible.h:15
attribute and attribute_property contracts
#define BBM_ATTR_POST(OP)
Definition: attribute.h:155
Convert a string to an object and vice versa.
Definition: aggregatebsdf.h:29
std::string toString(const T &)
toString alias
Definition: stringconvert.h:594
decltype(auto) value(T &&t)
return the value of an attribute, or if not an attribute the object
Definition: attribute_value.h:20
Base declaration of attribute; further specialized below.
Definition: attribute.h:26
Definition: named.h:325
attribute & operator=(const T &t)
Assignment operator.
Definition: attribute.h:69
attribute(U &&... u)
Forward constructor.
Definition: attribute.h:55
std::string toString(void) const
Custom toString.
Definition: attribute.h:80
PROP prop
Definition: attribute.h:40
typename PROP::type type
Definition: attribute.h:39
type _value
Definition: attribute.h:145
attribute(const T &t)
Copy Constructor.
Definition: attribute.h:47
const type & value(void) const
Definition: attribute.h:65
type & value(void)
Definition: attribute.h:64
attribute(const type &t)
Value constructor.
Definition: attribute.h:106
static attribute fromString(const std::string &str)
Custom fromString.
Definition: attribute.h:83
attribute(void)=default
Default construstor.