ADTF
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
result_description.h
Go to the documentation of this file.
1
7
8#ifndef _A_UTILS_CORE_RESULT_DESCRIPTION_H_
9#define _A_UTILS_CORE_RESULT_DESCRIPTION_H_
10
11#include <cstdint>
12#include <type_traits>
13
14namespace A_UTILS_NS
15{
16
17namespace detail
18{
19
25template<typename DescriptionType>
27{
28 using description_type = DescriptionType;
29 using reference_counted_object_type = ireference_counted_object<DescriptionType>;
30
32 static constexpr std::uint64_t error_code_bit = (std::uint64_t)1 << 63;
34 static constexpr std::uint64_t error_code_bitmask = ~error_code_bit;
35
43 static constexpr tBool is_detailed_description_set(const std::uint64_t i_pDescription) noexcept
44 {
45 //if the error code bit is not set, but other bits, detailed result was allocated
46 return 0 == (i_pDescription & error_code_bit)
47 && 0 != (i_pDescription & error_code_bitmask);
48 }
49
56 static constexpr tBool is_error_code_set(const std::uint64_t i_pDescription) noexcept
57 {
58 //the error code bit indicates whether only the error code is set
59 return error_code_bit == (i_pDescription & error_code_bit);
60 }
61};//struct result_description_traits
62
63
79template<typename DescriptionType>
80struct result_description
81{
82 using self_type = result_description<DescriptionType>;
83 using desc_type = DescriptionType;
85
86 constexpr result_description() noexcept : m_pDetailedResult(0)
87 {}
88
89 constexpr result_description(result_description&& oOther) noexcept: m_pDetailedResult(oOther.m_pDetailedResult)
90 {
91 oOther.m_pDetailedResult = 0;
92 }
93
94 result_description(const result_description& oOther) noexcept: result_description()
95 {
96 *this = oOther;
97 }
98
99 result_description& operator=(const result_description& oOther) noexcept
100 {
101 using reference_counted_impl_type =
102 typename traits_type::reference_counted_object_type;
103
104 if (&oOther != this)
105 {
106 if (traits_type::is_detailed_description_set(m_pDetailedResult))
107 {
108 reinterpret_cast<reference_counted_impl_type*>(m_pDetailedResult)->RemoveReference();
109 }
110 m_pDetailedResult = oOther.m_pDetailedResult;
111 if (traits_type::is_detailed_description_set(m_pDetailedResult))
112 {
113 reinterpret_cast<reference_counted_impl_type*>(m_pDetailedResult)->AddReference();
114 }
115 }
116 return *this;
117 }
118
119 ~result_description() noexcept
120 {
121 if (traits_type::is_detailed_description_set(m_pDetailedResult))
122 {
123 using reference_counted_impl_type= typename traits_type::reference_counted_object_type;
124 reinterpret_cast<reference_counted_impl_type*>(m_pDetailedResult)->RemoveReference();
125 }
126 }
127
148 template<typename Implementation, typename... Args>
149 static self_type make_result_description(const tErrorCode& i_oErrorCode, Args&&... args) noexcept;
150
156 static constexpr self_type make_result_description(const tErrorCode& i_oErrorCode) noexcept
157 {
158 //use the entire pointer for the error code and set the error code bit appropriately
159 //the user doesn't want to allocate space by calling this function, so just DON'T!
160 return self_type(i_oErrorCode.value);
161 }
162
169 desc_type const* get_detailed_description() const noexcept
170 {
171 //make sure, detailed description instead of error code is set
172 if (traits_type::is_detailed_description_set(m_pDetailedResult))
173 {
174 return &reinterpret_cast<typename traits_type::reference_counted_object_type*>(m_pDetailedResult)->GetObject();
175 }
176 return nullptr;
177 }
178
185 constexpr tErrorCode get_error_code() const noexcept
186 {
187 //only return the error code if only the error code was set!
188 if (traits_type::is_error_code_set(m_pDetailedResult))
189 {
190 return tErrorCode{
191 static_cast<tErrorCode::error_code_type>(
192 (m_pDetailedResult | 0xFFFFFFFF00000000)
194 };
195 }
196 return tErrorCode{ 0 };
197 }
198
199private:
200 // On all systems, a 64Bit variable for storage
201 // the most significant bits are used for user flags
202 // size of pointer part is system dependent, lower bits
203 std::uint64_t m_pDetailedResult;
204
205 constexpr result_description(std::uint64_t nErrorCode) noexcept :
206 //highly optimized code to bypass the cast on negative error codes...
207 m_pDetailedResult(((nErrorCode & 0xFFFFFFFF) | traits_type::error_code_bit))
208 {
209 }
210};//struct result_description
211
219template<typename T>
221 const result_description<T>& i_oRHS) noexcept
222{
223 //we put the tests inside this function so it will be available for all specializations
224
225 static_assert(sizeof(std::uintptr_t) <= 8,
226 "result_description pointers must always have a size of 8 Byte or less!");
227 static_assert(sizeof(result_description<T>) == 8,
228 "Description type unsupported size!");
229 static_assert(std::is_standard_layout<result_description<T>>::value,
230 "Description type is not of standard layout!");
231
232 return i_oLHS.get_error_code() == i_oRHS.get_error_code()
233 && i_oLHS.get_detailed_description() == i_oRHS.get_detailed_description();
234}
235
243template<typename T>
245 const result_description<T>& i_oRHS) noexcept
246{
247 return !(i_oLHS == i_oRHS);
248}
249
250}
251
252}//ns A_UTILS_NS
253
254#endif // _A_UTILS_CORE_RESULT_DESCRIPTION_H_
bool tBool
The tBool defines the type for the Values tTrue and tFalse (platform and compiler dependent).
ADTF A_UTIL Namespace - Within adtf this is used as util or adtf_util.
Definition d_ptr.h:11
tBool operator!=(const result_description< T > &i_oLHS, const result_description< T > &i_oRHS) noexcept
Compare two result description objects for inequality.
tBool operator==(const result_description< T > &i_oLHS, const result_description< T > &i_oRHS) noexcept
Compare two result description objects for equality.
Traits type for the result description.
static constexpr std::uint64_t error_code_bit
The error code bit indicating whether only the error code (1) was set or not (0)
DescriptionType description_type
The description type.
static constexpr tBool is_detailed_description_set(const std::uint64_t i_pDescription) noexcept
Check whether the detailed description was allocated.
static constexpr std::uint64_t error_code_bitmask
The error code bitmask to mask out the error code bit.
static constexpr tBool is_error_code_set(const std::uint64_t i_pDescription) noexcept
Check whether only the error code was set.
64 Bit error type has max 63 Bit large pointer type member variable
static self_type make_result_description(const tErrorCode &i_oErrorCode, Args &&... args) noexcept
Allocate an object being able to store detailed error information.
constexpr tErrorCode get_error_code() const noexcept
Get the error code if only the error code was set.
result_description< detail::IErrorDescription > self_type
static constexpr self_type make_result_description(const tErrorCode &i_oErrorCode) noexcept
Make the result description object only with an error code.
desc_type const * get_detailed_description() const noexcept
Get the detailed description if any was allocated.
result_description_traits< detail::IErrorDescription > traits_type