QuickCppLib  0.10
Eliminate all the tedious hassle when making state-of-the-art C++ 14 - 23 libraries!
quickcpplib::_xxx::detach_cast Namespace Reference

Namespaces

 detail
 
 traits
 Namespace for user specialised traits.
 

Typedefs

template<class T >
using byte_array_reference = byte(&)[sizeof(T)]
 A reference to a byte array sized the same as T More...
 
template<class T >
using const_byte_array_reference = const byte(&)[sizeof(T)]
 A const reference to a byte array sized the same as const T More...
 

Functions

template<class T , typename std::enable_if<(!detail::is_bit_cast_valid< detail::byte_array_wrapper< T >, T >() &&!traits::enable_reinterpret_detach_cast< typename std::decay< T >::type >::value), bool >::type = true>
constexpr QUICKCPPLIB_NODISCARD byte_array_reference< T > detach_cast (const T &,...) noexcept
 Detaches a live object into its detached byte representation, ending the lifetime of the input object, and beginning the lifetime of an array of byte sized exactly the size of the input object at the same memory location, which is returned. All references to the input object become INVALID. Any use of the input object after detachment has occurred is illegal! More...
 
template<class T , typename std::enable_if<(!detail::is_bit_cast_valid< T, detail::byte_array_wrapper< T >>() &&!traits::enable_reinterpret_attach_cast< typename std::decay< T >::type >::value), bool >::type = true>
constexpr QUICKCPPLIB_NODISCARD T & attach_cast (const_byte_array_reference< T > &,...) noexcept
 Reattaches a previously detached object, beginning the lifetime of the output object, and ending the lifetime of the input array of byte. All references to the input byte array become INVALID. Any use of the input array after attachment has occurred is illegal! More...
 
template<class T , typename std::enable_if<(detail::is_bit_cast_valid< detail::byte_array_wrapper< T >, T >() &&!traits::enable_reinterpret_detach_cast< typename std::decay< T >::type >::value), bool >::type = true>
constexpr QUICKCPPLIB_NODISCARD byte_array_reference< T > detach_cast (T &v, detail::bit_castable_overload={}) noexcept
 Detaches a non-const bit-castable object into its detached non-const byte representation, ending the lifetime of the input object. Defined behaviour in C++ 20 (though only the clang compiler currently reliably does not copy the byte array twice. GCC avoids the memory copy for small objects, MSVC always copies the byte array twice). More...
 
template<class T , typename std::enable_if<(detail::is_bit_cast_valid< const detail::byte_array_wrapper< T >, const T >() &&!traits::enable_reinterpret_detach_cast< typename std::decay< T >::type >::value), bool >::type = true>
constexpr QUICKCPPLIB_NODISCARD const_byte_array_reference< T > detach_cast (const T &v, detail::bit_castable_overload={}) noexcept
 Detaches a const bit-castable object into its detached const byte representation, ending the lifetime of the input object. Defined behaviour in C++ 20 (though only the clang compiler currently reliably does not copy the byte array twice. GCC avoids the memory copy for small objects, MSVC always copies the byte array twice). More...
 
template<class T , typename std::enable_if<(detail::is_bit_cast_valid< T, detail::byte_array_wrapper< T >>() &&!traits::enable_reinterpret_attach_cast< typename std::decay< T >::type >::value &&!std::is_const< T >::value), bool >::type = true>
constexpr QUICKCPPLIB_NODISCARD T & attach_cast (byte_array_reference< T > v, detail::bit_castable_overload={}) noexcept
 Attaches a non-const bit-castable object from its detached non-const byte representation, ending the lifetime of the input array. Defined behaviour in C++ 20 (though only the clang compiler currently reliably does not copy the byte array twice. GCC avoids the memory copy for small objects, MSVC always copies the byte array twice). More...
 
template<class T , typename std::enable_if<(detail::is_bit_cast_valid< T, const detail::byte_array_wrapper< T >>() &&!traits::enable_reinterpret_attach_cast< typename std::decay< T >::type >::value &&std::is_const< T >::value), bool >::type = true>
constexpr QUICKCPPLIB_NODISCARD const T & attach_cast (const_byte_array_reference< T > v, detail::bit_castable_overload={}) noexcept
 Attaches a const bit-castable object from its detached const byte representation, ending the lifetime of the input array. Defined behaviour in C++ 20 (though only the clang compiler currently reliably does not copy the byte array twice. GCC avoids the memory copy for small objects, MSVC always copies the byte array twice). More...
 
template<class T , typename std::enable_if<(!detail::is_bit_cast_valid< detail::byte_array_wrapper< T >, T >() &&traits::enable_reinterpret_detach_cast< typename std::decay< T >::type >::value), bool >::type = true>
constexpr QUICKCPPLIB_NODISCARD byte_array_reference< T > detach_cast (T &v, detail::reinterpret_cast_overload={}) noexcept
 Reinterpret casts a non-const object reference into a non-const byte representation. Pure undefined behaviour. Available only if traits::enable_reinterpret_detach_cast<T> is true for the type. More...
 
template<class T , typename std::enable_if<(!detail::is_bit_cast_valid< const detail::byte_array_wrapper< T >, const T >() &&traits::enable_reinterpret_detach_cast< typename std::decay< T >::type >::value), bool >::type = true>
constexpr QUICKCPPLIB_NODISCARD const_byte_array_reference< T > detach_cast (const T &v, detail::reinterpret_cast_overload={}) noexcept
 Reinterpret casts a const object reference into a const byte representation. Pure undefined behaviour. Available only if traits::enable_reinterpret_detach_cast<T> is true for the type. More...
 
template<class T , typename std::enable_if<(!detail::is_bit_cast_valid< T, detail::byte_array_wrapper< T >>() &&traits::enable_reinterpret_attach_cast< typename std::decay< T >::type >::value &&!std::is_const< T >::value), bool >::type = true>
constexpr QUICKCPPLIB_NODISCARD T & attach_cast (byte_array_reference< T > v, detail::reinterpret_cast_overload={}) noexcept
 Reinterpret casts a const byte representation into a const object. Pure undefined behaviour. Available only if traits::enable_reinterpret_attach_cast<T> is true for the type. More...
 
template<class T , typename std::enable_if<(!detail::is_bit_cast_valid< const T, const detail::byte_array_wrapper< T >>() &&traits::enable_reinterpret_attach_cast< typename std::decay< T >::type >::value &&std::is_const< T >::value), bool >::type = true>
constexpr QUICKCPPLIB_NODISCARD T & attach_cast (const_byte_array_reference< T > v, detail::reinterpret_cast_overload={}) noexcept
 Reinterpret casts a non-const byte representation into a non-const object. Pure undefined behaviour. Available only if traits::enable_reinterpret_attach_cast<T> is true for the type. More...
 

Typedef Documentation

◆ byte_array_reference

template<class T >
using quickcpplib::_xxx::detach_cast::byte_array_reference = typedef byte (&)[sizeof(T)]

A reference to a byte array sized the same as T

◆ const_byte_array_reference

template<class T >
using quickcpplib::_xxx::detach_cast::const_byte_array_reference = typedef const byte (&)[sizeof(T)]

A const reference to a byte array sized the same as const T

Function Documentation

◆ detach_cast() [1/5]

template<class T , typename std::enable_if<(!detail::is_bit_cast_valid< detail::byte_array_wrapper< T >, T >() &&!traits::enable_reinterpret_detach_cast< typename std::decay< T >::type >::value), bool >::type = true>
constexpr QUICKCPPLIB_NODISCARD byte_array_reference<T> quickcpplib::_xxx::detach_cast::detach_cast ( const T &  ,
  ... 
)
inlineconstexprnoexcept

Detaches a live object into its detached byte representation, ending the lifetime of the input object, and beginning the lifetime of an array of byte sized exactly the size of the input object at the same memory location, which is returned. All references to the input object become INVALID. Any use of the input object after detachment has occurred is illegal!

Implementation notes: If the input type is bit castable, bit casting is used to implement detachment using defined behaviour in C++ 20. Otherwise traits::enable_reinterpret_detach_cast<T> is used to determine whether to implement detachment using undefined behaviour by reinterpret casting.

117  { //
118  static_assert(!std::is_same<T, T>::value, "In C++ 20, detach_cast(T) is defined behaviour only for types which are bit castable. " //
119  "Set traits::enable_reinterpret_detach_cast<T> for specific types if you don't mind undefined behaviour.");
120  }

◆ attach_cast() [1/5]

template<class T , typename std::enable_if<(!detail::is_bit_cast_valid< T, detail::byte_array_wrapper< T >>() &&!traits::enable_reinterpret_attach_cast< typename std::decay< T >::type >::value), bool >::type = true>
constexpr QUICKCPPLIB_NODISCARD T& quickcpplib::_xxx::detach_cast::attach_cast ( const_byte_array_reference< T > &  ,
  ... 
)
inlineconstexprnoexcept

Reattaches a previously detached object, beginning the lifetime of the output object, and ending the lifetime of the input array of byte. All references to the input byte array become INVALID. Any use of the input array after attachment has occurred is illegal!

Implementation notes: If the output type is bit castable, bit casting is used to implement attachment using defined behaviour in C++ 20. Otherwise traits::enable_reinterpret_attach_cast<T> is used to determine whether to implement attachment using undefined behaviour by reinterpret casting.

135  { //
136  static_assert(!std::is_same<T, T>::value, "In C++ 20, attach_cast(T) is defined behaviour only for types which are bit castable. " //
137  "Set traits::enable_reinterpret_attach_cast<T> for specific types if you don't mind undefined behaviour.");
138  }

◆ detach_cast() [2/5]

template<class T , typename std::enable_if<(detail::is_bit_cast_valid< detail::byte_array_wrapper< T >, T >() &&!traits::enable_reinterpret_detach_cast< typename std::decay< T >::type >::value), bool >::type = true>
constexpr QUICKCPPLIB_NODISCARD byte_array_reference<T> quickcpplib::_xxx::detach_cast::detach_cast ( T &  v,
detail::bit_castable_overload  = {} 
)
inlineconstexprnoexcept

Detaches a non-const bit-castable object into its detached non-const byte representation, ending the lifetime of the input object. Defined behaviour in C++ 20 (though only the clang compiler currently reliably does not copy the byte array twice. GCC avoids the memory copy for small objects, MSVC always copies the byte array twice).

148  {}) noexcept
149  {
150  // Bit cast and copy the input object into a stack allocated byte array. This
151  // is defined behaviour for trivially copyable types.
152  auto buffer(bit_cast<detail::byte_array_wrapper<T>>(v));
153  // Cast input reference to output reference. Using the cast reference is defined
154  // behaviour for a few special functions e.g. memcpy()
155  auto &ret = reinterpret_cast<byte_array_reference<T>>(v);
156  // Copy the detached byte representation back over the input storage. This ends
157  // the lifetime of the input object, which is defined behaviour due to it being
158  // trivially copyable. The compiler now knows that the output reference does not
159  // alias the same object given by the input reference.
160  memcpy(&ret, buffer.value, sizeof(T));
161  // Return a reference to the byte array representing the detached object.
162  return ret;
163  }
constexpr To bit_cast(const From &from, detail::static_cast_overload={}) noexcept
Bit cast emulation chosen if types are move relocating or trivally copyable, have identical size,...
Definition: bit_cast.hpp:121

◆ detach_cast() [3/5]

template<class T , typename std::enable_if<(detail::is_bit_cast_valid< const detail::byte_array_wrapper< T >, const T >() &&!traits::enable_reinterpret_detach_cast< typename std::decay< T >::type >::value), bool >::type = true>
constexpr QUICKCPPLIB_NODISCARD const_byte_array_reference<T> quickcpplib::_xxx::detach_cast::detach_cast ( const T &  v,
detail::bit_castable_overload  = {} 
)
inlineconstexprnoexcept

Detaches a const bit-castable object into its detached const byte representation, ending the lifetime of the input object. Defined behaviour in C++ 20 (though only the clang compiler currently reliably does not copy the byte array twice. GCC avoids the memory copy for small objects, MSVC always copies the byte array twice).

172  {}) noexcept
173  {
174  const auto buffer(bit_cast<const detail::byte_array_wrapper<T>>(v));
175  auto &ret = const_cast<byte_array_reference<T>>(reinterpret_cast<const_byte_array_reference<T>>(v));
176  memcpy(&ret, buffer.value, sizeof(T));
177  return ret;
178  }

◆ attach_cast() [2/5]

template<class T , typename std::enable_if<(detail::is_bit_cast_valid< T, detail::byte_array_wrapper< T >>() &&!traits::enable_reinterpret_attach_cast< typename std::decay< T >::type >::value &&!std::is_const< T >::value), bool >::type = true>
constexpr QUICKCPPLIB_NODISCARD T& quickcpplib::_xxx::detach_cast::attach_cast ( byte_array_reference< T >  v,
detail::bit_castable_overload  = {} 
)
inlineconstexprnoexcept

Attaches a non-const bit-castable object from its detached non-const byte representation, ending the lifetime of the input array. Defined behaviour in C++ 20 (though only the clang compiler currently reliably does not copy the byte array twice. GCC avoids the memory copy for small objects, MSVC always copies the byte array twice).

188  {}) noexcept
189  {
190  // Bit cast and copy the input byte array into a stack allocated object. This
191  // is defined behaviour for trivially copyable types.
192  T temp(bit_cast<T>(v));
193  // Cast input reference to output reference. Using the cast reference is defined
194  // behaviour for a few special functions e.g. memcpy()
195  T &ret = reinterpret_cast<T &>(v);
196  // Trivially copyable types can be memcpy()ied, this begins lifetime in the destination
197  memcpy(&ret, &temp, sizeof(T));
198  // Return a reference to the new object.
199  return ret;
200  }

◆ attach_cast() [3/5]

template<class T , typename std::enable_if<(detail::is_bit_cast_valid< T, const detail::byte_array_wrapper< T >>() &&!traits::enable_reinterpret_attach_cast< typename std::decay< T >::type >::value &&std::is_const< T >::value), bool >::type = true>
constexpr QUICKCPPLIB_NODISCARD const T& quickcpplib::_xxx::detach_cast::attach_cast ( const_byte_array_reference< T >  v,
detail::bit_castable_overload  = {} 
)
inlineconstexprnoexcept

Attaches a const bit-castable object from its detached const byte representation, ending the lifetime of the input array. Defined behaviour in C++ 20 (though only the clang compiler currently reliably does not copy the byte array twice. GCC avoids the memory copy for small objects, MSVC always copies the byte array twice).

210  {}) noexcept
211  {
212  using nonconst = typename std::remove_const<T>::type;
213  T temp(bit_cast<nonconst>(v));
214  nonconst &ret = const_cast<nonconst &>(reinterpret_cast<T &>(v));
215  memcpy(&ret, &temp, sizeof(T));
216  return ret;
217  }

◆ detach_cast() [4/5]

template<class T , typename std::enable_if<(!detail::is_bit_cast_valid< detail::byte_array_wrapper< T >, T >() &&traits::enable_reinterpret_detach_cast< typename std::decay< T >::type >::value), bool >::type = true>
constexpr QUICKCPPLIB_NODISCARD byte_array_reference<T> quickcpplib::_xxx::detach_cast::detach_cast ( T &  v,
detail::reinterpret_cast_overload  = {} 
)
inlineconstexprnoexcept

Reinterpret casts a non-const object reference into a non-const byte representation. Pure undefined behaviour. Available only if traits::enable_reinterpret_detach_cast<T> is true for the type.

226  {}) noexcept
227  {
228  return reinterpret_cast<byte_array_reference<T>>(v);
229  }

◆ detach_cast() [5/5]

template<class T , typename std::enable_if<(!detail::is_bit_cast_valid< const detail::byte_array_wrapper< T >, const T >() &&traits::enable_reinterpret_detach_cast< typename std::decay< T >::type >::value), bool >::type = true>
constexpr QUICKCPPLIB_NODISCARD const_byte_array_reference<T> quickcpplib::_xxx::detach_cast::detach_cast ( const T &  v,
detail::reinterpret_cast_overload  = {} 
)
inlineconstexprnoexcept

Reinterpret casts a const object reference into a const byte representation. Pure undefined behaviour. Available only if traits::enable_reinterpret_detach_cast<T> is true for the type.

237  {}) noexcept
238  {
239  return reinterpret_cast<const_byte_array_reference<T>>(v);
240  }

◆ attach_cast() [4/5]

template<class T , typename std::enable_if<(!detail::is_bit_cast_valid< T, detail::byte_array_wrapper< T >>() &&traits::enable_reinterpret_attach_cast< typename std::decay< T >::type >::value &&!std::is_const< T >::value), bool >::type = true>
constexpr QUICKCPPLIB_NODISCARD T& quickcpplib::_xxx::detach_cast::attach_cast ( byte_array_reference< T >  v,
detail::reinterpret_cast_overload  = {} 
)
inlineconstexprnoexcept

Reinterpret casts a const byte representation into a const object. Pure undefined behaviour. Available only if traits::enable_reinterpret_attach_cast<T> is true for the type.

249  {}) noexcept
250  {
251  return reinterpret_cast<T &>(v);
252  }

◆ attach_cast() [5/5]

template<class T , typename std::enable_if<(!detail::is_bit_cast_valid< const T, const detail::byte_array_wrapper< T >>() &&traits::enable_reinterpret_attach_cast< typename std::decay< T >::type >::value &&std::is_const< T >::value), bool >::type = true>
constexpr QUICKCPPLIB_NODISCARD T& quickcpplib::_xxx::detach_cast::attach_cast ( const_byte_array_reference< T >  v,
detail::reinterpret_cast_overload  = {} 
)
inlineconstexprnoexcept

Reinterpret casts a non-const byte representation into a non-const object. Pure undefined behaviour. Available only if traits::enable_reinterpret_attach_cast<T> is true for the type.

261  {}) noexcept
262  {
263  return reinterpret_cast<T &>(v);
264  }