ADTF  3.18.2
result_description.h
Go to the documentation of this file.
1 
8 #ifndef _A_UTILS_CORE_RESULT_DESCRIPTION_H_
9 #define _A_UTILS_CORE_RESULT_DESCRIPTION_H_
10 
11 #include <cstdint>
12 
13 namespace A_UTILS_NS
14 {
15 
16 namespace detail
17 {
18 
24 template<typename DescriptionType>
26 {
27  using description_type = DescriptionType;
29 
31  static constexpr std::uint64_t error_code_bit = (std::uint64_t)1 << 63;
33  static constexpr std::uint64_t error_code_bitmask = ~error_code_bit;
34 
42  static tBool is_detailed_description_set(const std::uint64_t i_pDescription) noexcept
43  {
44  //if the error code bit is not set, but other bits, detailed result was allocated
45  return 0 == (i_pDescription & error_code_bit)
46  && 0 != (i_pDescription & error_code_bitmask);
47  }
48 
55  static tBool is_error_code_set(const std::uint64_t i_pDescription) noexcept
56  {
57  //the error code bit indicates whether only the error code is set
58  return error_code_bit == (i_pDescription & error_code_bit);
59  }
60 };//struct result_description_traits
61 
62 
78 template<typename DescriptionType>
80 {
82  using desc_type = DescriptionType;
84 
85  result_description() : m_pDetailedResult(0)
86  {}
87 
89  {
90  *this = oOther;
91  }
92 
93  result_description& operator=(const result_description& oOther)
94  {
95  using reference_counted_impl_type =
96  typename traits_type::reference_counted_object_type;
97 
98  if (&oOther != this)
99  {
100  if (traits_type::is_detailed_description_set(m_pDetailedResult))
101  {
102  reinterpret_cast<reference_counted_impl_type*>(m_pDetailedResult)->RemoveReference();
103  }
104  m_pDetailedResult = oOther.m_pDetailedResult;
105  if (traits_type::is_detailed_description_set(m_pDetailedResult))
106  {
107  reinterpret_cast<reference_counted_impl_type*>(m_pDetailedResult)->AddReference();
108  }
109  }
110  return *this;
111  }
112 
113  ~result_description()
114  {
115  if (traits_type::is_detailed_description_set(m_pDetailedResult))
116  {
117  using reference_counted_impl_type= typename traits_type::reference_counted_object_type;
118  reinterpret_cast<reference_counted_impl_type*>(m_pDetailedResult)->RemoveReference();
119  }
120  }
121 
142  template<typename Implementation, typename... Args>
143  static self_type make_result_description(const tErrorCode& i_oErrorCode, Args&&... args) noexcept;
144 
150  static self_type make_result_description(const tErrorCode& i_oErrorCode) noexcept
151  {
152  //use the entire pointer for the error code and set the error code bit appropriately
153  //the user doesn't want to allocate space by calling this function, so just DON'T!
154  return self_type(i_oErrorCode.value);
155  }
156 
163  desc_type const* get_detailed_description() const noexcept
164  {
165  //make sure, detailed description instead of error code is set
166  if (traits_type::is_detailed_description_set(m_pDetailedResult))
167  {
168  return &reinterpret_cast<typename traits_type::reference_counted_object_type*>(m_pDetailedResult)->GetObject();
169  }
170  return nullptr;
171  }
172 
179  tErrorCode get_error_code() const noexcept
180  {
181  //only return the error code if only the error code was set!
182  if (traits_type::is_error_code_set(m_pDetailedResult))
183  {
184  return tErrorCode{
185  static_cast<tErrorCode::error_code_type>(
186  (m_pDetailedResult | 0xFFFFFFFF00000000)
188  };
189  }
190  return tErrorCode{ 0 };
191  }
192 
193 private:
194  // On all systems, a 64Bit variable for storage
195  // the most significant bits are used for user flags
196  // size of pointer part is system dependent, lower bits
197  std::uint64_t m_pDetailedResult;
198 
199  result_description(std::uint64_t nErrorCode) :
200  //highly optimized code to bypass the cast on negative error codes...
201  m_pDetailedResult(((nErrorCode & 0xFFFFFFFF) | traits_type::error_code_bit))
202  {
203  }
204 };//struct result_description
205 
213 template<typename T>
215  const result_description<T>& i_oRHS) noexcept
216 {
217  //we put the tests inside this function so it will be available for all specializations
218 
219  static_assert(sizeof(std::uintptr_t) <= 8,
220  "result_description pointers must always have a size of 8 Byte or less!");
221  static_assert(sizeof(result_description<T>) == 8,
222  "Description type unsupported size!");
223  static_assert(std::is_standard_layout<result_description<T>>::value,
224  "Description type is not of standard layout!");
225 
226  return i_oLHS.get_error_code() == i_oRHS.get_error_code()
227  && i_oLHS.get_detailed_description() == i_oRHS.get_detailed_description();
228 }
229 
237 template<typename T>
239  const result_description<T>& i_oRHS) noexcept
240 {
241  return !(i_oLHS == i_oRHS);
242 }
243 
244 }
245 
246 }//ns A_UTILS_NS
247 
248 #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 adtf::util or adtf_util.
Definition: d_ptr.h:11
tBool operator==(const cMultiArrayIndex &o_A, const cMultiArrayIndex &o_B)
Comparison operator.
tBool operator!=(const cMultiArrayIndex &o_A, const cMultiArrayIndex &o_B)
Comparison operator.
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)
static tBool is_detailed_description_set(const std::uint64_t i_pDescription) noexcept
Check whether the detailed description was allocated.
DescriptionType description_type
The description type.
static tBool is_error_code_set(const std::uint64_t i_pDescription) noexcept
Check whether only the error code was set.
static constexpr std::uint64_t error_code_bitmask
The error code bitmask to mask out the error code bit.
64 Bit error type has max 63 Bit large pointer type member variable
tErrorCode get_error_code() const noexcept
Get the error code if only the error code was set.
DescriptionType desc_type
Description type.
static self_type make_result_description(const tErrorCode &i_oErrorCode) noexcept
Make the result description object only with an error code.
static self_type make_result_description(const tErrorCode &i_oErrorCode, Args &&... args) noexcept
Allocate an object being able to store detailed error information.
result_description< DescriptionType > self_type
Self type.
result_description_traits< DescriptionType > traits_type
Traits type abbreviation.
desc_type const * get_detailed_description() const noexcept
Get the detailed description if any was allocated.