16#ifndef ROOT7_RColumnElement
17#define ROOT7_RColumnElement
34#ifndef R__LITTLE_ENDIAN
37#define R__LITTLE_ENDIAN 1
39#define R__LITTLE_ENDIAN 0
71template <std::
size_t N>
72static void CopyBswap(
void *destination,
const void *source, std::size_t count)
76 for (std::size_t i = 0; i < count; ++i) {
82#if R__LITTLE_ENDIAN == 0
84void ByteSwapIfNecessary(T &
value)
86 constexpr auto N =
sizeof(T);
88 void *valuePtr = &
value;
90 *
reinterpret_cast<bswap_value_type *
>(valuePtr) = swapped;
93#define ByteSwapIfNecessary(x) ((void)0)
100template <
typename DestT,
typename SourceT>
101static void CastPack(
void *destination,
const void *source, std::size_t count)
103 static_assert(std::is_convertible_v<SourceT, DestT>);
104 auto dst =
reinterpret_cast<DestT *
>(destination);
105 auto src =
reinterpret_cast<const SourceT *
>(source);
106 for (std::size_t i = 0; i < count; ++i) {
108 ByteSwapIfNecessary(dst[i]);
116template <
typename DestT,
typename SourceT>
117static void CastUnpack(
void *destination,
const void *source, std::size_t count)
119 auto dst =
reinterpret_cast<DestT *
>(destination);
120 auto src =
reinterpret_cast<const SourceT *
>(source);
121 for (std::size_t i = 0; i < count; ++i) {
122 SourceT val =
src[i];
123 ByteSwapIfNecessary(val);
131template <
typename DestT,
typename SourceT>
132static void CastSplitPack(
void *destination,
const void *source, std::size_t count)
134 constexpr std::size_t
N =
sizeof(DestT);
135 auto splitArray =
reinterpret_cast<char *
>(destination);
136 auto src =
reinterpret_cast<const SourceT *
>(source);
137 for (std::size_t i = 0; i < count; ++i) {
139 ByteSwapIfNecessary(val);
140 for (std::size_t
b = 0;
b <
N; ++
b) {
141 splitArray[
b * count + i] =
reinterpret_cast<const char *
>(&val)[
b];
149template <
typename DestT,
typename SourceT>
150static void CastSplitUnpack(
void *destination,
const void *source, std::size_t count)
152 constexpr std::size_t
N =
sizeof(SourceT);
153 auto dst =
reinterpret_cast<DestT *
>(destination);
154 auto splitArray =
reinterpret_cast<const char *
>(source);
155 for (std::size_t i = 0; i < count; ++i) {
157 for (std::size_t
b = 0;
b <
N; ++
b) {
158 reinterpret_cast<char *
>(&val)[
b] = splitArray[
b * count + i];
160 ByteSwapIfNecessary(val);
168template <
typename DestT,
typename SourceT>
169static void CastDeltaSplitPack(
void *destination,
const void *source, std::size_t count)
171 constexpr std::size_t
N =
sizeof(DestT);
172 auto src =
reinterpret_cast<const SourceT *
>(source);
173 auto splitArray =
reinterpret_cast<char *
>(destination);
174 for (std::size_t i = 0; i < count; ++i) {
175 DestT val = (i == 0) ?
src[0] :
src[i] -
src[i - 1];
176 ByteSwapIfNecessary(val);
177 for (std::size_t
b = 0;
b <
N; ++
b) {
178 splitArray[
b * count + i] =
reinterpret_cast<char *
>(&val)[
b];
186template <
typename DestT,
typename SourceT>
187static void CastDeltaSplitUnpack(
void *destination,
const void *source, std::size_t count)
189 constexpr std::size_t
N =
sizeof(SourceT);
190 auto splitArray =
reinterpret_cast<const char *
>(source);
191 auto dst =
reinterpret_cast<DestT *
>(destination);
192 for (std::size_t i = 0; i < count; ++i) {
194 for (std::size_t
b = 0;
b <
N; ++
b) {
195 reinterpret_cast<char *
>(&val)[
b] = splitArray[
b * count + i];
197 ByteSwapIfNecessary(val);
198 dst[i] = (i == 0) ? val : dst[i - 1] + val;
205template <
typename DestT,
typename SourceT>
206static void CastZigzagSplitPack(
void *destination,
const void *source, std::size_t count)
208 using UDestT = std::make_unsigned_t<DestT>;
209 constexpr std::size_t kNBitsDestT =
sizeof(DestT) * 8;
210 constexpr std::size_t
N =
sizeof(DestT);
211 auto src =
reinterpret_cast<const SourceT *
>(source);
212 auto splitArray =
reinterpret_cast<char *
>(destination);
213 for (std::size_t i = 0; i < count; ++i) {
214 UDestT val = (
static_cast<DestT
>(
src[i]) << 1) ^ (
static_cast<DestT
>(
src[i]) >> (kNBitsDestT - 1));
215 ByteSwapIfNecessary(val);
216 for (std::size_t
b = 0;
b <
N; ++
b) {
217 splitArray[
b * count + i] =
reinterpret_cast<char *
>(&val)[
b];
225template <
typename DestT,
typename SourceT>
226static void CastZigzagSplitUnpack(
void *destination,
const void *source, std::size_t count)
228 using USourceT = std::make_unsigned_t<SourceT>;
229 constexpr std::size_t
N =
sizeof(SourceT);
230 auto splitArray =
reinterpret_cast<const char *
>(source);
231 auto dst =
reinterpret_cast<DestT *
>(destination);
232 for (std::size_t i = 0; i < count; ++i) {
234 for (std::size_t
b = 0;
b <
N; ++
b) {
235 reinterpret_cast<char *
>(&val)[
b] = splitArray[
b * count + i];
237 ByteSwapIfNecessary(val);
238 dst[i] =
static_cast<SourceT
>((val >> 1) ^ -(
static_cast<SourceT
>(val) & 1));
245namespace Experimental {
278 template <
typename CppT =
void>
288 virtual void Pack(
void *destination,
void *source, std::size_t count)
const
290 std::memcpy(destination, source, count);
294 virtual void Unpack(
void *destination,
void *source, std::size_t count)
const
296 std::memcpy(destination, source, count);
307template <
typename CppT>
315 void Pack(
void *dst,
void *
src, std::size_t count)
const final
317#if R__LITTLE_ENDIAN == 1
320 CopyBswap<sizeof(CppT)>(dst,
src, count);
323 void Unpack(
void *dst,
void *
src, std::size_t count)
const final
325#if R__LITTLE_ENDIAN == 1
328 CopyBswap<sizeof(CppT)>(dst,
src, count);
337template <
typename CppT,
typename NarrowT>
345 void Pack(
void *dst,
void *
src, std::size_t count)
const final { CastPack<NarrowT, CppT>(dst,
src, count); }
346 void Unpack(
void *dst,
void *
src, std::size_t count)
const final { CastUnpack<CppT, NarrowT>(dst,
src, count); }
354template <
typename CppT,
typename NarrowT>
362 void Pack(
void *dst,
void *
src, std::size_t count)
const final { CastSplitPack<NarrowT, CppT>(dst,
src, count); }
363 void Unpack(
void *dst,
void *
src, std::size_t count)
const final { CastSplitUnpack<CppT, NarrowT>(dst,
src, count); }
371template <
typename CppT,
typename NarrowT>
379 void Pack(
void *dst,
void *
src, std::size_t count)
const final
381 CastDeltaSplitPack<NarrowT, CppT>(dst,
src, count);
383 void Unpack(
void *dst,
void *
src, std::size_t count)
const final
385 CastDeltaSplitUnpack<CppT, NarrowT>(dst,
src, count);
394template <
typename CppT,
typename NarrowT>
402 void Pack(
void *dst,
void *
src, std::size_t count)
const final
404 CastZigzagSplitPack<NarrowT, CppT>(dst,
src, count);
406 void Unpack(
void *dst,
void *
src, std::size_t count)
const final
408 CastZigzagSplitUnpack<CppT, NarrowT>(dst,
src, count);
420template <
typename CppT, EColumnType ColumnT = EColumnType::kUnknown>
425 throw RException(
R__FAIL(std::string(
"internal error: no column mapping for this C++ type: ") +
440 static constexpr std::size_t
kSize =
sizeof(char);
447 static constexpr std::size_t
kSize =
sizeof(std::int8_t);
454 static constexpr std::size_t
kSize =
sizeof(std::uint8_t);
461 static constexpr std::size_t
kSize =
sizeof(std::int16_t);
468 static constexpr std::size_t
kSize =
sizeof(std::uint16_t);
475 static constexpr std::size_t
kSize =
sizeof(std::int32_t);
482 static constexpr std::size_t
kSize =
sizeof(std::uint32_t);
489 static constexpr std::size_t
kSize =
sizeof(std::int64_t);
496 static constexpr std::size_t
kSize =
sizeof(std::uint64_t);
503 static constexpr std::size_t
kSize =
sizeof(float);
536 static constexpr bool kIsMappable =
false;
538 static constexpr std::size_t kBitsOnStorage = 64;
543 void Pack(
void *dst,
void *
src, std::size_t count)
const final
546 auto uint64Array =
reinterpret_cast<std::uint64_t *
>(dst);
547 for (std::size_t i = 0; i < count; ++i) {
549 (
static_cast<std::uint64_t
>(srcArray[i].GetTag()) << 44) | (srcArray[i].GetIndex() & 0x0fffffffffff);
550#if R__LITTLE_ENDIAN == 0
556 void Unpack(
void *dst,
void *
src, std::size_t count)
const final
558 auto uint64Array =
reinterpret_cast<std::uint64_t *
>(
src);
560 for (std::size_t i = 0; i < count; ++i) {
561#if R__LITTLE_ENDIAN == 1
562 const auto value = uint64Array[i];
575 static constexpr bool kIsMappable =
false;
577 static constexpr std::size_t kBitsOnStorage = 1;
582 void Pack(
void *dst,
void *
src, std::size_t count)
const final;
583 void Unpack(
void *dst,
void *
src, std::size_t count)
const final;
586#define __RCOLUMNELEMENT_SPEC_BODY(CppT, BaseT, BitsOnStorage) \
587 static constexpr std::size_t kSize = sizeof(CppT); \
588 static constexpr std::size_t kBitsOnStorage = BitsOnStorage; \
589 RColumnElement() : BaseT(kSize) {} \
590 bool IsMappable() const final \
592 return kIsMappable; \
594 std::size_t GetBitsOnStorage() const final \
596 return kBitsOnStorage; \
604#define DECLARE_RCOLUMNELEMENT_SPEC(CppT, ColumnT, BitsOnStorage, BaseT, ...) \
606 class RColumnElement<CppT, ColumnT> : public BaseT __VA_ARGS__ { \
608 __RCOLUMNELEMENT_SPEC_BODY(CppT, BaseT, BitsOnStorage) \
610#define DECLARE_RCOLUMNELEMENT_SPEC_SIMPLE(CppT, ColumnT, BitsOnStorage) \
612 class RColumnElement<CppT, ColumnT> : public RColumnElementBase { \
614 static constexpr bool kIsMappable = true; \
615 __RCOLUMNELEMENT_SPEC_BODY(CppT, RColumnElementBase, BitsOnStorage) \
632 <std::int16_t, std::int16_t>);
634 <std::int16_t, std::uint16_t>);
639 <std::uint16_t, std::uint16_t>);
641 <std::uint16_t, std::int16_t>);
646 <std::int32_t, std::int32_t>);
648 <std::int32_t, std::uint32_t>);
653 <std::uint32_t, std::uint32_t>);
655 <std::uint32_t, std::int32_t>);
660 <std::int64_t, std::int64_t>);
662 <std::int64_t, std::uint64_t>);
665 <std::int64_t, std::uint32_t>);
667 <std::int64_t, std::int32_t>);
669 <std::int64_t, std::uint32_t>);
674 <std::uint64_t, std::uint64_t>);
676 <std::uint64_t, std::int64_t>);
688 <std::uint64_t, std::uint32_t>);
690 <std::uint64_t, std::uint64_t>);
692 <std::uint64_t, std::uint32_t>);
694template <
typename CppT>
700 case EColumnType::kSwitch:
return std::make_unique<RColumnElement<CppT, EColumnType::kSwitch>>();
701 case EColumnType::kByte:
return std::make_unique<RColumnElement<CppT, EColumnType::kByte>>();
702 case EColumnType::kChar:
return std::make_unique<RColumnElement<CppT, EColumnType::kChar>>();
703 case EColumnType::kBit:
return std::make_unique<RColumnElement<CppT, EColumnType::kBit>>();
704 case EColumnType::kReal64:
return std::make_unique<RColumnElement<CppT, EColumnType::kReal64>>();
705 case EColumnType::kReal32:
return std::make_unique<RColumnElement<CppT, EColumnType::kReal32>>();
706 case EColumnType::kInt64:
return std::make_unique<RColumnElement<CppT, EColumnType::kInt64>>();
707 case EColumnType::kUInt64:
return std::make_unique<RColumnElement<CppT, EColumnType::kUInt64>>();
708 case EColumnType::kInt32:
return std::make_unique<RColumnElement<CppT, EColumnType::kInt32>>();
709 case EColumnType::kUInt32:
return std::make_unique<RColumnElement<CppT, EColumnType::kUInt32>>();
710 case EColumnType::kInt16:
return std::make_unique<RColumnElement<CppT, EColumnType::kInt16>>();
711 case EColumnType::kUInt16:
return std::make_unique<RColumnElement<CppT, EColumnType::kUInt16>>();
712 case EColumnType::kInt8:
return std::make_unique<RColumnElement<CppT, EColumnType::kInt8>>();
713 case EColumnType::kUInt8:
return std::make_unique<RColumnElement<CppT, EColumnType::kUInt8>>();
731std::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...
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-...
RColumnElementBase(RColumnElementBase &&other)=default
virtual bool IsMappable() const
Derived, typed classes tell whether the on-storage layout is bitwise identical to the memory layout.
virtual std::size_t GetBitsOnStorage() const
std::size_t GetPackedSize(std::size_t nElements=1U) const
RColumnElementBase(const RColumnElementBase &other)=default
RColumnElementBase & operator=(const RColumnElementBase &other)=delete
std::size_t fSize
Size of the C++ value that corresponds to the on-disk element.
static std::string GetTypeName(EColumnType type)
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-...
RColumnElementBase(std::size_t size)
std::size_t GetSize() const
virtual ~RColumnElementBase()=default
static std::unique_ptr< RColumnElementBase > Generate(EColumnType type)
If CppT == void, use the default C++ type for the given column type.
Base class for columns storing elements of wider in-memory types, such as 64bit in-memory offsets to ...
static constexpr bool kIsMappable
RColumnElementCastLE(std::size_t size)
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-...
Base class for delta + split columns (index columns) whose on-storage representation is little-endian...
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-...
RColumnElementDeltaSplitLE(std::size_t size)
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-...
static constexpr bool kIsMappable
Base class for columns whose on-storage representation is little-endian.
RColumnElementLE(std::size_t size)
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-...
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 split columns whose on-storage representation is little-endian.
RColumnElementSplitLE(std::size_t size)
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-...
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...
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
RColumnElementZigzagSplitLE(std::size_t size)
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-...
std::size_t GetBitsOnStorage() const final
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-...
std::size_t GetBitsOnStorage() const final
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.
Base class for all ROOT issued exceptions.
RClusterSize ClusterSize_t
This file contains a specialised ROOT message handler to test for diagnostic in unit tests.
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::uint32_t.