58 float16_t() =
default;
59 float16_t(std::nullptr_t, uint16_t bytes): bytes(bytes)
62 float16_t(
const float16_t& value) =
default;
63 float16_t(
double value): bytes(half_float::encode_flt16(value))
67 float16_t& operator=(
const float16_t& value) =
default;
68 float16_t& operator=(
double value)
70 bytes = half_float::encode_flt16(value);
74 operator double()
const
76 return half_float::decode_flt16<double>(bytes);
83inline constexpr tAttribute::tInMemory::eEndianess get_byteorder()
86 return tAttribute::tInMemory::eEndianess::endian_little;
88 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
89 return tAttribute::tInMemory::eEndianess::endian_little;
90 #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
91 return tAttribute::tInMemory::eEndianess::endian_big;
93 static_assert(
false,
"Unsupported byte order");
101 if constexpr (
sizeof(T) == 1)
105 else if constexpr (
sizeof(T) == 2)
107 #if defined(__llvm__) || defined(__GNUC__)
108 return __builtin_bswap16(value);
109 #elif defined(_MSC_VER)
110 return _byteswap_ushort(value);
112 static_assert(
false,
"Missing intrinsic for this compiler?");
115 else if constexpr (
sizeof(T) == 4)
117 #if defined(__llvm__) || defined(__GNUC__)
118 return __builtin_bswap32(value);
119 #elif defined(_MSC_VER)
120 return _byteswap_ulong(value);
122 static_assert(
false,
"Missing intrinsic for this compiler?");
125 else if constexpr (
sizeof(T) == 8)
127 #if defined(__llvm__) || defined(__GNUC__)
128 return __builtin_bswap64(value);
129 #elif defined(_MSC_VER)
130 return _byteswap_uint64(value);
132 static_assert(
false,
"Missing intrinsic for this compiler?");
138inline float16_t byte_swap<float16_t>(float16_t value)
140 return half_float::detail::bit_cast<float16_t>(byte_swap(half_float::detail::bit_cast<uint16_t>(value)));
144inline float byte_swap<float>(
float value)
146 return half_float::detail::bit_cast<float>(byte_swap(half_float::detail::bit_cast<uint32_t>(value)));
150inline double byte_swap<double>(
double value)
152 return half_float::detail::bit_cast<double>(byte_swap(half_float::detail::bit_cast<uint64_t>(value)));
155template <
typename T,
bool swap>
158 static T access(
const std::byte* pReadPosition)
162 return byte_swap(*(
reinterpret_cast<const T*
>(pReadPosition)));
166 return *(
reinterpret_cast<const T*
>(pReadPosition));
174 static double access(
const std::byte* pReadPosition)
176 return float16_t(
nullptr, Accessor<uint16_t, swap>::access(pReadPosition));
180template <
typename T,
bool swap>
181T access(
const std::byte* pReadPosition)
183 return Accessor<T, swap>::access(pReadPosition);
189T get_attribute_value(
const tAttribute::tInMemory& oSource,
const detail::tConstBuffer& sBuffer,
size_t nIndex)
191 const auto pReadPosition =
static_cast<const std::byte*
>(sBuffer.pData) + oSource.offset + oSource.stride * nIndex;
192 if (oSource.endianess == detail::get_byteorder())
194 return detail::access<T, false>(pReadPosition);
198 return detail::access<T, true>(pReadPosition);
203void set_attribute_value(
const tAttribute::tInMemory& oDestination,
const detail::tBuffer& sBuffer,
size_t nIndex, T value)
205 const auto pWritePosition =
reinterpret_cast<T*
>(
static_cast<std::byte*
>(sBuffer.pData) + oDestination.offset + oDestination.stride * nIndex);
206 if (oDestination.endianess == detail::get_byteorder())
208 *pWritePosition = value;
212 *pWritePosition = detail::byte_swap(value);
216using AttributeValue = std::variant<bool,
231 switch (oSource.type)
233 case tAttribute::tDataType::dt_boolean:
return get_attribute_value<bool>(oSource.sInMemory, sBuffer, nIndex);
234 case tAttribute::tDataType::dt_int8:
return get_attribute_value<int8_t>(oSource.sInMemory, sBuffer, nIndex);
235 case tAttribute::tDataType::dt_uint8:
return get_attribute_value<uint8_t>(oSource.sInMemory, sBuffer, nIndex);
236 case tAttribute::tDataType::dt_int16:
return get_attribute_value<int16_t>(oSource.sInMemory, sBuffer, nIndex);
237 case tAttribute::tDataType::dt_uint16:
return get_attribute_value<uint16_t>(oSource.sInMemory, sBuffer, nIndex);
238 case tAttribute::tDataType::dt_int32:
return get_attribute_value<int32_t>(oSource.sInMemory, sBuffer, nIndex);
239 case tAttribute::tDataType::dt_uint32:
return get_attribute_value<uint32_t>(oSource.sInMemory, sBuffer, nIndex);
240 case tAttribute::tDataType::dt_int64:
return get_attribute_value<int64_t>(oSource.sInMemory, sBuffer, nIndex);
241 case tAttribute::tDataType::dt_uint64:
return get_attribute_value<uint64_t>(oSource.sInMemory, sBuffer, nIndex);
242 case tAttribute::tDataType::dt_float16:
return get_attribute_value<float16_t>(oSource.sInMemory, sBuffer, nIndex);
243 case tAttribute::tDataType::dt_float32:
return get_attribute_value<float>(oSource.sInMemory, sBuffer, nIndex);
244 case tAttribute::tDataType::dt_float64:
return get_attribute_value<double>(oSource.sInMemory, sBuffer, nIndex);
245 case tAttribute::tDataType::dt_computed_from_index:
return oSource.sComputed.Get(nIndex);
248 throw std::runtime_error(
"unexpected");
251inline void set_attribute_value(
const tAttribute& oDestination,
const detail::tBuffer& sBuffer,
size_t nIndex, AttributeValue value)
253 std::visit([&](
const auto& typed_value)
255 switch (oDestination.type)
257 case tAttribute::tDataType::dt_boolean: set_attribute_value<bool>(oDestination.sInMemory, sBuffer, nIndex,
static_cast<bool>(typed_value));
break;
258 case tAttribute::tDataType::dt_int8:
259 set_attribute_value<int8_t>(oDestination.sInMemory, sBuffer, nIndex,
static_cast<int8_t
>(typed_value));
261 case tAttribute::tDataType::dt_uint8:
262 set_attribute_value<uint8_t>(oDestination.sInMemory, sBuffer, nIndex,
static_cast<uint8_t
>( typed_value));
264 case tAttribute::tDataType::dt_int16:
265 set_attribute_value<int16_t>(oDestination.sInMemory, sBuffer, nIndex,
static_cast<int16_t
>( typed_value));
267 case tAttribute::tDataType::dt_uint16:
268 set_attribute_value<uint16_t>(oDestination.sInMemory, sBuffer, nIndex,
static_cast<uint16_t
>(typed_value));
270 case tAttribute::tDataType::dt_int32:
271 set_attribute_value<int32_t>(oDestination.sInMemory, sBuffer, nIndex,
static_cast<int32_t
>(typed_value));
273 case tAttribute::tDataType::dt_uint32:
274 set_attribute_value<uint32_t>(oDestination.sInMemory, sBuffer, nIndex,
static_cast<uint32_t
>(typed_value));
276 case tAttribute::tDataType::dt_int64:
277 set_attribute_value<int64_t>(oDestination.sInMemory, sBuffer, nIndex,
static_cast<int64_t
>(typed_value));
279 case tAttribute::tDataType::dt_uint64:
280 set_attribute_value<uint64_t>(oDestination.sInMemory, sBuffer, nIndex,
static_cast<uint64_t
>(typed_value));
282 case tAttribute::tDataType::dt_float16:
283 set_attribute_value<float16_t>(oDestination.sInMemory, sBuffer, nIndex,
float16_t(
static_cast<double>(typed_value)));
285 case tAttribute::tDataType::dt_float32:
286 set_attribute_value<float>(oDestination.sInMemory, sBuffer, nIndex,
static_cast<float>(typed_value));
288 case tAttribute::tDataType::dt_float64:
289 set_attribute_value<double>(oDestination.sInMemory, sBuffer, nIndex,
static_cast<double>(typed_value));
291 case tAttribute::tDataType::dt_computed_from_index:
throw std::runtime_error(
"cannot write to computed attribute");
300inline T to_type(AttributeValue value)
302 if constexpr (std::is_same_v<AttributeValue, T>)
308 return std::visit([](
const auto& typed_value) -> T
310 return static_cast<T
>(typed_value);