16#ifndef ROOT7_RColumnElement
17#define ROOT7_RColumnElement
37#ifndef R__LITTLE_ENDIAN
40#define R__LITTLE_ENDIAN 1
42#define R__LITTLE_ENDIAN 0
74template <std::
size_t N>
75void CopyBswap(
void *destination,
const void *source, std::size_t count)
79 for (std::size_t i = 0; i < count; ++i) {
85#if R__LITTLE_ENDIAN == 0
87void ByteSwapIfNecessary(T &
value)
89 constexpr auto N =
sizeof(T);
91 void *valuePtr = &
value;
93 *
reinterpret_cast<bswap_value_type *
>(valuePtr) = swapped;
96#define ByteSwapIfNecessary(x) ((void)0)
103template <
typename DestT,
typename SourceT>
104static void CastPack(
void *destination,
const void *source, std::size_t count)
106 static_assert(std::is_convertible_v<SourceT, DestT>);
107 auto dst =
reinterpret_cast<DestT *
>(destination);
108 auto src =
reinterpret_cast<const SourceT *
>(source);
109 for (std::size_t i = 0; i < count; ++i) {
111 ByteSwapIfNecessary(dst[i]);
119template <
typename DestT,
typename SourceT>
120static void CastUnpack(
void *destination,
const void *source, std::size_t count)
122 auto dst =
reinterpret_cast<DestT *
>(destination);
123 auto src =
reinterpret_cast<const SourceT *
>(source);
124 for (std::size_t i = 0; i < count; ++i) {
125 SourceT val =
src[i];
126 ByteSwapIfNecessary(val);
134template <
typename DestT,
typename SourceT>
135static void CastSplitPack(
void *destination,
const void *source, std::size_t count)
137 constexpr std::size_t
N =
sizeof(DestT);
138 auto splitArray =
reinterpret_cast<char *
>(destination);
139 auto src =
reinterpret_cast<const SourceT *
>(source);
140 for (std::size_t i = 0; i < count; ++i) {
142 ByteSwapIfNecessary(val);
143 for (std::size_t
b = 0;
b <
N; ++
b) {
144 splitArray[
b * count + i] =
reinterpret_cast<const char *
>(&val)[
b];
152template <
typename DestT,
typename SourceT>
153static void CastSplitUnpack(
void *destination,
const void *source, std::size_t count)
155 constexpr std::size_t
N =
sizeof(SourceT);
156 auto dst =
reinterpret_cast<DestT *
>(destination);
157 auto splitArray =
reinterpret_cast<const char *
>(source);
158 for (std::size_t i = 0; i < count; ++i) {
160 for (std::size_t
b = 0;
b <
N; ++
b) {
161 reinterpret_cast<char *
>(&val)[
b] = splitArray[
b * count + i];
163 ByteSwapIfNecessary(val);
171template <
typename DestT,
typename SourceT>
172static void CastDeltaSplitPack(
void *destination,
const void *source, std::size_t count)
174 constexpr std::size_t
N =
sizeof(DestT);
175 auto src =
reinterpret_cast<const SourceT *
>(source);
176 auto splitArray =
reinterpret_cast<char *
>(destination);
177 for (std::size_t i = 0; i < count; ++i) {
178 DestT val = (i == 0) ?
src[0] :
src[i] -
src[i - 1];
179 ByteSwapIfNecessary(val);
180 for (std::size_t
b = 0;
b <
N; ++
b) {
181 splitArray[
b * count + i] =
reinterpret_cast<char *
>(&val)[
b];
189template <
typename DestT,
typename SourceT>
190static void CastDeltaSplitUnpack(
void *destination,
const void *source, std::size_t count)
192 constexpr std::size_t
N =
sizeof(SourceT);
193 auto splitArray =
reinterpret_cast<const char *
>(source);
194 auto dst =
reinterpret_cast<DestT *
>(destination);
195 for (std::size_t i = 0; i < count; ++i) {
197 for (std::size_t
b = 0;
b <
N; ++
b) {
198 reinterpret_cast<char *
>(&val)[
b] = splitArray[
b * count + i];
200 ByteSwapIfNecessary(val);
201 dst[i] = (i == 0) ? val : dst[i - 1] + val;
208template <
typename DestT,
typename SourceT>
209static void CastZigzagSplitPack(
void *destination,
const void *source, std::size_t count)
211 using UDestT = std::make_unsigned_t<DestT>;
212 constexpr std::size_t kNBitsDestT =
sizeof(DestT) * 8;
213 constexpr std::size_t
N =
sizeof(DestT);
214 auto src =
reinterpret_cast<const SourceT *
>(source);
215 auto splitArray =
reinterpret_cast<char *
>(destination);
216 for (std::size_t i = 0; i < count; ++i) {
217 UDestT val = (
static_cast<DestT
>(
src[i]) << 1) ^ (
static_cast<DestT
>(
src[i]) >> (kNBitsDestT - 1));
218 ByteSwapIfNecessary(val);
219 for (std::size_t
b = 0;
b <
N; ++
b) {
220 splitArray[
b * count + i] =
reinterpret_cast<char *
>(&val)[
b];
228template <
typename DestT,
typename SourceT>
229static void CastZigzagSplitUnpack(
void *destination,
const void *source, std::size_t count)
231 using USourceT = std::make_unsigned_t<SourceT>;
232 constexpr std::size_t
N =
sizeof(SourceT);
233 auto splitArray =
reinterpret_cast<const char *
>(source);
234 auto dst =
reinterpret_cast<DestT *
>(destination);
235 for (std::size_t i = 0; i < count; ++i) {
237 for (std::size_t
b = 0;
b <
N; ++
b) {
238 reinterpret_cast<char *
>(&val)[
b] = splitArray[
b * count + i];
240 ByteSwapIfNecessary(val);
241 dst[i] =
static_cast<SourceT
>((val >> 1) ^ -(
static_cast<SourceT
>(val) & 1));
248namespace Experimental {
284 template <
typename CppT =
void>
297 virtual void Pack(
void *destination,
void *source, std::size_t count)
const
299 std::memcpy(destination, source, count);
303 virtual void Unpack(
void *destination,
void *source, std::size_t count)
const
305 std::memcpy(destination, source, count);
317template <
typename CppT>
325 void Pack(
void *dst,
void *
src, std::size_t count)
const final
327#if R__LITTLE_ENDIAN == 1
330 CopyBswap<sizeof(CppT)>(dst,
src, count);
333 void Unpack(
void *dst,
void *
src, std::size_t count)
const final
335#if R__LITTLE_ENDIAN == 1
338 CopyBswap<sizeof(CppT)>(dst,
src, count);
347template <
typename CppT,
typename NarrowT>
357 void Pack(
void *dst,
void *
src, std::size_t count)
const final { CastPack<NarrowT, CppT>(dst,
src, count); }
358 void Unpack(
void *dst,
void *
src, std::size_t count)
const final { CastUnpack<CppT, NarrowT>(dst,
src, count); }
366template <
typename CppT,
typename NarrowT>
376 void Pack(
void *dst,
void *
src, std::size_t count)
const final { CastSplitPack<NarrowT, CppT>(dst,
src, count); }
377 void Unpack(
void *dst,
void *
src, std::size_t count)
const final { CastSplitUnpack<CppT, NarrowT>(dst,
src, count); }
385template <
typename CppT,
typename NarrowT>
396 void Pack(
void *dst,
void *
src, std::size_t count)
const final
398 CastDeltaSplitPack<NarrowT, CppT>(dst,
src, count);
400 void Unpack(
void *dst,
void *
src, std::size_t count)
const final
402 CastDeltaSplitUnpack<CppT, NarrowT>(dst,
src, count);
411template <
typename CppT,
typename NarrowT>
422 void Pack(
void *dst,
void *
src, std::size_t count)
const final
424 CastZigzagSplitPack<NarrowT, CppT>(dst,
src, count);
426 void Unpack(
void *dst,
void *
src, std::size_t count)
const final
428 CastZigzagSplitUnpack<CppT, NarrowT>(dst,
src, count);
440template <
typename CppT, EColumnType ColumnT = EColumnType::kUnknown>
445 throw RException(
R__FAIL(std::string(
"internal error: no column mapping for this C++ type: ") +
460 static constexpr std::size_t
kSize =
sizeof(std::byte);
467 static constexpr std::size_t
kSize =
sizeof(char);
474 static constexpr std::size_t
kSize =
sizeof(std::int8_t);
481 static constexpr std::size_t
kSize =
sizeof(std::uint8_t);
488 static constexpr std::size_t
kSize =
sizeof(std::int16_t);
495 static constexpr std::size_t
kSize =
sizeof(std::uint16_t);
502 static constexpr std::size_t
kSize =
sizeof(std::int32_t);
509 static constexpr std::size_t
kSize =
sizeof(std::uint32_t);
516 static constexpr std::size_t
kSize =
sizeof(std::int64_t);
523 static constexpr std::size_t
kSize =
sizeof(std::uint64_t);
530 static constexpr std::size_t
kSize =
sizeof(float);
563 struct RSwitchElement {
569 static constexpr bool kIsMappable =
false;
571 static constexpr std::size_t kBitsOnStorage = 96;
575 void Pack(
void *dst,
void *
src, std::size_t count)
const final
578 auto dstArray =
reinterpret_cast<unsigned char *
>(dst);
579 for (std::size_t i = 0; i < count; ++i) {
580 RSwitchElement element{srcArray[i].
GetIndex(), srcArray[i].GetTag()};
581#if R__LITTLE_ENDIAN == 0
585 memcpy(dstArray + i * 12, &element, 12);
589 void Unpack(
void *dst,
void *
src, std::size_t count)
const final
591 auto srcArray =
reinterpret_cast<unsigned char *
>(
src);
593 for (std::size_t i = 0; i < count; ++i) {
594 RSwitchElement element;
595 memcpy(&element, srcArray + i * 12, 12);
596#if R__LITTLE_ENDIAN == 0
608 static constexpr bool kIsMappable =
false;
610 static constexpr std::size_t kBitsOnStorage = 1;
614 void Pack(
void *dst,
void *
src, std::size_t count)
const final;
615 void Unpack(
void *dst,
void *
src, std::size_t count)
const final;
621 static constexpr bool kIsMappable =
false;
622 static constexpr std::size_t
kSize =
sizeof(float);
623 static constexpr std::size_t kBitsOnStorage = 16;
627 void Pack(
void *dst,
void *
src, std::size_t count)
const final
629 float *floatArray =
reinterpret_cast<float *
>(
src);
630 std::uint16_t *uint16Array =
reinterpret_cast<std::uint16_t *
>(dst);
632 for (std::size_t i = 0; i < count; ++i) {
634 ByteSwapIfNecessary(uint16Array[i]);
638 void Unpack(
void *dst,
void *
src, std::size_t count)
const final
640 float *floatArray =
reinterpret_cast<float *
>(dst);
641 std::uint16_t *uint16Array =
reinterpret_cast<std::uint16_t *
>(
src);
643 for (std::size_t i = 0; i < count; ++i) {
644 ByteSwapIfNecessary(floatArray[i]);
650#define __RCOLUMNELEMENT_SPEC_BODY(CppT, BaseT, BitsOnStorage) \
651 static constexpr std::size_t kSize = sizeof(CppT); \
652 static constexpr std::size_t kBitsOnStorage = BitsOnStorage; \
653 RColumnElement() : BaseT(kSize, kBitsOnStorage) {} \
654 bool IsMappable() const final \
656 return kIsMappable; \
664#define DECLARE_RCOLUMNELEMENT_SPEC(CppT, ColumnT, BitsOnStorage, BaseT, ...) \
666 class RColumnElement<CppT, ColumnT> : public BaseT __VA_ARGS__ { \
668 __RCOLUMNELEMENT_SPEC_BODY(CppT, BaseT, BitsOnStorage) \
670#define DECLARE_RCOLUMNELEMENT_SPEC_SIMPLE(CppT, ColumnT, BitsOnStorage) \
672 class RColumnElement<CppT, ColumnT> : public RColumnElementBase { \
674 static constexpr bool kIsMappable = true; \
675 __RCOLUMNELEMENT_SPEC_BODY(CppT, RColumnElementBase, BitsOnStorage) \
694 <std::int16_t, std::int16_t>);
696 <std::int16_t, std::uint16_t>);
701 <std::uint16_t, std::uint16_t>);
703 <std::uint16_t, std::int16_t>);
708 <std::int32_t, std::int32_t>);
710 <std::int32_t, std::uint32_t>);
715 <std::uint32_t, std::uint32_t>);
717 <std::uint32_t, std::int32_t>);
722 <std::int64_t, std::int64_t>);
724 <std::int64_t, std::uint64_t>);
727 <std::int64_t, std::uint32_t>);
729 <std::int64_t, std::int32_t>);
731 <std::int64_t, std::uint32_t>);
736 <std::uint64_t, std::uint64_t>);
738 <std::uint64_t, std::int64_t>);
750 <std::uint64_t, std::uint32_t>);
752 <std::uint64_t, std::uint64_t>);
754 <std::uint64_t, std::uint32_t>);
756template <
typename CppT>
762 case EColumnType::kSwitch:
return std::make_unique<RColumnElement<CppT, EColumnType::kSwitch>>();
763 case EColumnType::kByte:
return std::make_unique<RColumnElement<CppT, EColumnType::kByte>>();
764 case EColumnType::kChar:
return std::make_unique<RColumnElement<CppT, EColumnType::kChar>>();
765 case EColumnType::kBit:
return std::make_unique<RColumnElement<CppT, EColumnType::kBit>>();
766 case EColumnType::kReal64:
return std::make_unique<RColumnElement<CppT, EColumnType::kReal64>>();
767 case EColumnType::kReal32:
return std::make_unique<RColumnElement<CppT, EColumnType::kReal32>>();
768 case EColumnType::kReal16:
return std::make_unique<RColumnElement<CppT, EColumnType::kReal16>>();
769 case EColumnType::kInt64:
return std::make_unique<RColumnElement<CppT, EColumnType::kInt64>>();
770 case EColumnType::kUInt64:
return std::make_unique<RColumnElement<CppT, EColumnType::kUInt64>>();
771 case EColumnType::kInt32:
return std::make_unique<RColumnElement<CppT, EColumnType::kInt32>>();
772 case EColumnType::kUInt32:
return std::make_unique<RColumnElement<CppT, EColumnType::kUInt32>>();
773 case EColumnType::kInt16:
return std::make_unique<RColumnElement<CppT, EColumnType::kInt16>>();
774 case EColumnType::kUInt16:
return std::make_unique<RColumnElement<CppT, EColumnType::kUInt16>>();
775 case EColumnType::kInt8:
return std::make_unique<RColumnElement<CppT, EColumnType::kInt8>>();
776 case EColumnType::kUInt8:
return std::make_unique<RColumnElement<CppT, EColumnType::kUInt8>>();
794std::unique_ptr<RColumnElementBase> RColumnElementBase::Generate<void>(
EColumnType type);
#define DECLARE_RCOLUMNELEMENT_SPEC_SIMPLE(CppT, ColumnT, BitsOnStorage)
#define DECLARE_RCOLUMNELEMENT_SPEC(CppT, ColumnT, BitsOnStorage, BaseT,...)
These macros are used to declare RColumnElement template specializations below.
#define R__FAIL(msg)
Short-hand to return an RResult<T> in an error state; the RError is implicitly converted into RResult...
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t src
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t Float_t Float_t Float_t Int_t Int_t UInt_t UInt_t Rectangle_t Int_t Int_t Window_t TString Int_t GCValues_t GetPrimarySelectionOwner GetDisplay GetScreen GetColormap GetNativeEvent const char const char dpyName wid window const char font_name cursor keysym reg const char only_if_exist regb h Point_t winding char text const char depth char const char Int_t count const char ColorStruct_t color const char Pixmap_t Pixmap_t PictureAttributes_t attr const char char ret_data h unsigned char height h Atom_t Int_t ULong_t ULong_t unsigned char prop_list Atom_t Atom_t Atom_t Time_t type
A column element encapsulates the translation between basic C++ types and their column representation...
RColumnElementBase & operator=(const RColumnElementBase &other)=delete
std::size_t fBitsOnStorage
RColumnElementBase(std::size_t size, std::size_t bitsOnStorage=0)
std::size_t GetSize() const
virtual void Pack(void *destination, void *source, std::size_t count) const
If the on-storage layout and the in-memory layout differ, packing creates an on-disk page from an in-...
virtual void Unpack(void *destination, void *source, std::size_t count) const
If the on-storage layout and the in-memory layout differ, unpacking creates a memory page from an on-...
virtual bool IsMappable() const
Derived, typed classes tell whether the on-storage layout is bitwise identical to the memory layout.
static std::string GetTypeName(EColumnType type)
std::size_t fSize
Size of the C++ value that corresponds to the on-disk element.
std::size_t GetBitsOnStorage() const
RColumnElementBase(const RColumnElementBase &other)=default
virtual ~RColumnElementBase()=default
static std::unique_ptr< RColumnElementBase > Generate(EColumnType type)
If CppT == void, use the default C++ type for the given column type.
std::size_t GetPackedSize(std::size_t nElements=1U) const
RColumnElementBase(RColumnElementBase &&other)=default
Base class for columns storing elements of wider in-memory types, such as 64bit in-memory offsets to ...
void Pack(void *dst, void *src, std::size_t count) const final
If the on-storage layout and the in-memory layout differ, packing creates an on-disk page from an in-...
RColumnElementCastLE(std::size_t size, std::size_t bitsOnStorage)
void Unpack(void *dst, void *src, std::size_t count) const final
If the on-storage layout and the in-memory layout differ, unpacking creates a memory page from an on-...
static constexpr bool kIsMappable
Base class for delta + split columns (index columns) whose on-storage representation is little-endian...
void Pack(void *dst, void *src, std::size_t count) const final
If the on-storage layout and the in-memory layout differ, packing creates an on-disk page from an in-...
void Unpack(void *dst, void *src, std::size_t count) const final
If the on-storage layout and the in-memory layout differ, unpacking creates a memory page from an on-...
static constexpr bool kIsMappable
RColumnElementDeltaSplitLE(std::size_t size, std::size_t bitsOnStorage)
Base class for columns whose on-storage representation is little-endian.
RColumnElementLE(std::size_t size, std::size_t bitsOnStorage)
void Unpack(void *dst, void *src, std::size_t count) const final
If the on-storage layout and the in-memory layout differ, unpacking creates a memory page from an on-...
static constexpr bool kIsMappable
void Pack(void *dst, void *src, std::size_t count) const final
If the on-storage layout and the in-memory layout differ, packing creates an on-disk page from an in-...
Base class for split columns whose on-storage representation is little-endian.
void Pack(void *dst, void *src, std::size_t count) const final
If the on-storage layout and the in-memory layout differ, packing creates an on-disk page from an in-...
RColumnElementSplitLE(std::size_t size, std::size_t bitsOnStorage)
static constexpr bool kIsMappable
void Unpack(void *dst, void *src, std::size_t count) const final
If the on-storage layout and the in-memory layout differ, unpacking creates a memory page from an on-...
Base class for zigzag + split columns (signed integer columns) whose on-storage representation is lit...
RColumnElementZigzagSplitLE(std::size_t size, std::size_t bitsOnStorage)
void Pack(void *dst, void *src, std::size_t count) const final
If the on-storage layout and the in-memory layout differ, packing creates an on-disk page from an in-...
void Unpack(void *dst, void *src, std::size_t count) const final
If the on-storage layout and the in-memory layout differ, unpacking creates a memory page from an on-...
static constexpr bool kIsMappable
void Pack(void *dst, void *src, std::size_t count) const final
If the on-storage layout and the in-memory layout differ, packing creates an on-disk page from an in-...
bool IsMappable() const final
Derived, typed classes tell whether the on-storage layout is bitwise identical to the memory layout.
void Unpack(void *dst, void *src, std::size_t count) const final
If the on-storage layout and the in-memory layout differ, unpacking creates a memory page from an on-...
void Unpack(void *dst, void *src, std::size_t count) const final
If the on-storage layout and the in-memory layout differ, unpacking creates a memory page from an on-...
void Pack(void *dst, void *src, std::size_t count) const final
If the on-storage layout and the in-memory layout differ, packing creates an on-disk page from an in-...
bool IsMappable() const final
Derived, typed classes tell whether the on-storage layout is bitwise identical to the memory layout.
void Unpack(void *dst, void *src, std::size_t count) const final
If the on-storage layout and the in-memory layout differ, unpacking creates a memory page from an on-...
void Pack(void *dst, void *src, std::size_t count) const final
If the on-storage layout and the in-memory layout differ, packing creates an on-disk page from an in-...
bool IsMappable() const final
Derived, typed classes tell whether the on-storage layout is bitwise identical to the memory layout.
Holds the index and the tag of a kSwitch column.
ClusterSize_t GetIndex() const
Base class for all ROOT issued exceptions.
std::uint16_t FloatToHalf(float value)
Convert an IEEE single-precision float to half-precision.
float HalfToFloat(std::uint16_t value)
Convert an IEEE half-precision float to single-precision.
RClusterSize ClusterSize_t
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...
Helper templated class for swapping bytes; specializations for N={2,4,8} are provided below.
Wrap the integer in a struct in order to avoid template specialization clash with std::uint64_t.