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

Namespaces

namespace  detail
 
namespace  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
 
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
 

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>
QUICKCPPLIB_NODISCARD constexpr 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!
 
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>
QUICKCPPLIB_NODISCARD constexpr 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!
 
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>
QUICKCPPLIB_NODISCARD constexpr 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).
 
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>
QUICKCPPLIB_NODISCARD constexpr 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).
 
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>
QUICKCPPLIB_NODISCARD constexpr 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).
 
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>
QUICKCPPLIB_NODISCARD constexpr 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).
 
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>
QUICKCPPLIB_NODISCARD constexpr 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.
 
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>
QUICKCPPLIB_NODISCARD constexpr 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.
 
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>
QUICKCPPLIB_NODISCARD constexpr 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.
 
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>
QUICKCPPLIB_NODISCARD constexpr 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.
 

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>
QUICKCPPLIB_NODISCARD constexpr 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>
QUICKCPPLIB_NODISCARD constexpr 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>
QUICKCPPLIB_NODISCARD constexpr 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 }

◆ 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>
QUICKCPPLIB_NODISCARD constexpr 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>
QUICKCPPLIB_NODISCARD constexpr 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>
QUICKCPPLIB_NODISCARD constexpr 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>
QUICKCPPLIB_NODISCARD constexpr 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>
QUICKCPPLIB_NODISCARD constexpr 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>
QUICKCPPLIB_NODISCARD constexpr 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>
QUICKCPPLIB_NODISCARD constexpr 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 }