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
68template <std::
size_t N>
69static void CopyBswap(
void *destination,
const void *source, std::size_t count)
73 for (std::size_t i = 0; i < count; ++i) {
79#if R__LITTLE_ENDIAN == 0
81void ByteSwapIfNecessary(T &
value)
83 constexpr auto N =
sizeof(T);
85 void *valuePtr = &
value;
87 *
reinterpret_cast<bswap_value_type *
>(valuePtr) = swapped;
90#define ByteSwapIfNecessary(x) ((void)0)
97template <
typename DestT,
typename SourceT>
98static void CastPack(
void *destination,
const void *source, std::size_t count)
100 static_assert(std::is_convertible_v<SourceT, DestT>);
101 auto dst =
reinterpret_cast<DestT *
>(destination);
102 auto src =
reinterpret_cast<const SourceT *
>(source);
103 for (std::size_t i = 0; i < count; ++i) {
105 ByteSwapIfNecessary(dst[i]);
113template <
typename DestT,
typename SourceT>
114static void CastUnpack(
void *destination,
const void *source, std::size_t count)
116 auto dst =
reinterpret_cast<DestT *
>(destination);
117 auto src =
reinterpret_cast<const SourceT *
>(source);
118 for (std::size_t i = 0; i < count; ++i) {
119 SourceT val =
src[i];
120 ByteSwapIfNecessary(val);
128template <
typename DestT,
typename SourceT>
129static void CastSplitPack(
void *destination,
const void *source, std::size_t count)
131 constexpr std::size_t
N =
sizeof(DestT);
132 auto splitArray =
reinterpret_cast<char *
>(destination);
133 auto src =
reinterpret_cast<const SourceT *
>(source);
134 for (std::size_t i = 0; i < count; ++i) {
136 ByteSwapIfNecessary(val);
137 for (std::size_t
b = 0;
b <
N; ++
b) {
138 splitArray[
b * count + i] =
reinterpret_cast<const char *
>(&val)[
b];
146template <
typename DestT,
typename SourceT>
147static void CastSplitUnpack(
void *destination,
const void *source, std::size_t count)
149 constexpr std::size_t
N =
sizeof(SourceT);
150 auto dst =
reinterpret_cast<DestT *
>(destination);
151 auto splitArray =
reinterpret_cast<const char *
>(source);
152 for (std::size_t i = 0; i < count; ++i) {
154 for (std::size_t
b = 0;
b <
N; ++
b) {
155 reinterpret_cast<char *
>(&val)[
b] = splitArray[
b * count + i];
157 ByteSwapIfNecessary(val);
165template <
typename DestT,
typename SourceT>
166static void CastDeltaSplitPack(
void *destination,
const void *source, std::size_t count)
168 constexpr std::size_t
N =
sizeof(DestT);
169 auto src =
reinterpret_cast<const SourceT *
>(source);
170 auto splitArray =
reinterpret_cast<char *
>(destination);
171 for (std::size_t i = 0; i < count; ++i) {
172 DestT val = (i == 0) ?
src[0] :
src[i] -
src[i - 1];
173 ByteSwapIfNecessary(val);
174 for (std::size_t
b = 0;
b <
N; ++
b) {
175 splitArray[
b * count + i] =
reinterpret_cast<char *
>(&val)[
b];
183template <
typename DestT,
typename SourceT>
184static void CastDeltaSplitUnpack(
void *destination,
const void *source, std::size_t count)
186 constexpr std::size_t
N =
sizeof(SourceT);
187 auto splitArray =
reinterpret_cast<const char *
>(source);
188 auto dst =
reinterpret_cast<DestT *
>(destination);
189 for (std::size_t i = 0; i < count; ++i) {
191 for (std::size_t
b = 0;
b <
N; ++
b) {
192 reinterpret_cast<char *
>(&val)[
b] = splitArray[
b * count + i];
194 ByteSwapIfNecessary(val);
195 dst[i] = (i == 0) ? val : dst[i - 1] + val;
202namespace Experimental {
245 template <
typename CppT =
void>
251 void WriteTo(
void *destination, std::size_t count)
const {
265 virtual void Pack(
void *destination,
void *source, std::size_t count)
const
267 std::memcpy(destination, source, count);
271 virtual void Unpack(
void *destination,
void *source, std::size_t count)
const
273 std::memcpy(destination, source, count);
285template <
typename CppT>
291 void Pack(
void *dst,
void *
src, std::size_t count)
const final
293#if R__LITTLE_ENDIAN == 1
296 CopyBswap<sizeof(CppT)>(dst,
src, count);
299 void Unpack(
void *dst,
void *
src, std::size_t count)
const final
301#if R__LITTLE_ENDIAN == 1
304 CopyBswap<sizeof(CppT)>(dst,
src, count);
313template <
typename CppT,
typename NarrowT>
319 void Pack(
void *dst,
void *
src, std::size_t count)
const final { CastPack<NarrowT, CppT>(dst,
src, count); }
320 void Unpack(
void *dst,
void *
src, std::size_t count)
const final { CastUnpack<CppT, NarrowT>(dst,
src, count); }
328template <
typename CppT,
typename NarrowT>
334 void Pack(
void *dst,
void *
src, std::size_t count)
const final { CastSplitPack<NarrowT, CppT>(dst,
src, count); }
335 void Unpack(
void *dst,
void *
src, std::size_t count)
const final { CastSplitUnpack<CppT, NarrowT>(dst,
src, count); }
343template <
typename CppT,
typename NarrowT>
349 void Pack(
void *dst,
void *
src, std::size_t count)
const final
351 CastDeltaSplitPack<NarrowT, CppT>(dst,
src, count);
353 void Unpack(
void *dst,
void *
src, std::size_t count)
const final
355 CastDeltaSplitUnpack<CppT, NarrowT>(dst,
src, count);
367template <
typename CppT, EColumnType ColumnT = EColumnType::kUnknown>
372 throw RException(
R__FAIL(std::string(
"internal error: no column mapping for this C++ type: ") +
387 static constexpr std::size_t
kSize =
sizeof(char);
394 static constexpr std::size_t
kSize =
sizeof(std::int8_t);
401 static constexpr std::size_t
kSize =
sizeof(std::uint8_t);
408 static constexpr std::size_t
kSize =
sizeof(std::int16_t);
415 static constexpr std::size_t
kSize =
sizeof(std::uint16_t);
422 static constexpr std::size_t
kSize =
sizeof(std::int32_t);
429 static constexpr std::size_t
kSize =
sizeof(std::uint32_t);
436 static constexpr std::size_t
kSize =
sizeof(std::int64_t);
443 static constexpr std::size_t
kSize =
sizeof(std::uint64_t);
450 static constexpr std::size_t
kSize =
sizeof(float);
483 static constexpr bool kIsMappable =
false;
485 static constexpr std::size_t kBitsOnStorage = 1;
490 void Pack(
void *dst,
void *
src, std::size_t count)
const final;
491 void Unpack(
void *dst,
void *
src, std::size_t count)
const final;
497 static constexpr bool kIsMappable =
true;
498 static constexpr std::size_t
kSize =
sizeof(char);
499 static constexpr std::size_t kBitsOnStorage =
kSize * 8;
508 static constexpr bool kIsMappable =
true;
509 static constexpr std::size_t
kSize =
sizeof(char);
510 static constexpr std::size_t kBitsOnStorage =
kSize * 8;
519 static constexpr bool kIsMappable =
true;
520 static constexpr std::size_t
kSize =
sizeof(std::int8_t);
521 static constexpr std::size_t kBitsOnStorage =
kSize * 8;
523 bool IsMappable() const final {
return kIsMappable; }
530 static constexpr bool kIsMappable =
true;
531 static constexpr std::size_t
kSize =
sizeof(std::int8_t);
532 static constexpr std::size_t kBitsOnStorage =
kSize * 8;
534 bool IsMappable() const final {
return kIsMappable; }
541 static constexpr bool kIsMappable =
true;
542 static constexpr std::size_t
kSize =
sizeof(std::uint8_t);
543 static constexpr std::size_t kBitsOnStorage =
kSize * 8;
545 bool IsMappable() const final {
return kIsMappable; }
552 static constexpr bool kIsMappable =
true;
553 static constexpr std::size_t
kSize =
sizeof(std::uint8_t);
554 static constexpr std::size_t kBitsOnStorage =
kSize * 8;
556 bool IsMappable() const final {
return kIsMappable; }
561class RColumnElement<std::int16_t,
EColumnType::kInt16> :
public RColumnElementLE<std::int16_t> {
563 static constexpr std::size_t
kSize =
sizeof(std::int16_t);
564 static constexpr std::size_t kBitsOnStorage =
kSize * 8;
566 bool IsMappable() const final {
return kIsMappable; }
572 :
public RColumnElementSplitLE<std::int16_t, std::int16_t> {
574 static constexpr std::size_t
kSize =
sizeof(std::int16_t);
575 static constexpr std::size_t kBitsOnStorage =
kSize * 8;
577 bool IsMappable() const final {
return kIsMappable; }
582class RColumnElement<std::uint16_t,
EColumnType::kInt16> :
public RColumnElementLE<std::uint16_t> {
584 static constexpr std::size_t
kSize =
sizeof(std::uint16_t);
585 static constexpr std::size_t kBitsOnStorage =
kSize * 8;
587 bool IsMappable() const final {
return kIsMappable; }
593 :
public RColumnElementSplitLE<std::uint16_t, std::uint16_t> {
595 static constexpr std::size_t
kSize =
sizeof(std::uint16_t);
596 static constexpr std::size_t kBitsOnStorage =
kSize * 8;
598 bool IsMappable() const final {
return kIsMappable; }
603class RColumnElement<std::int32_t,
EColumnType::kInt32> :
public RColumnElementLE<std::int32_t> {
605 static constexpr std::size_t
kSize =
sizeof(std::int32_t);
606 static constexpr std::size_t kBitsOnStorage =
kSize * 8;
608 bool IsMappable() const final {
return kIsMappable; }
614 :
public RColumnElementSplitLE<std::int32_t, std::int32_t> {
616 static constexpr std::size_t
kSize =
sizeof(std::int32_t);
617 static constexpr std::size_t kBitsOnStorage =
kSize * 8;
619 bool IsMappable() const final {
return kIsMappable; }
624class RColumnElement<std::uint32_t,
EColumnType::kInt32> :
public RColumnElementLE<std::uint32_t> {
626 static constexpr std::size_t
kSize =
sizeof(std::uint32_t);
627 static constexpr std::size_t kBitsOnStorage =
kSize * 8;
629 bool IsMappable() const final {
return kIsMappable; }
635 :
public RColumnElementSplitLE<std::uint32_t, std::uint32_t> {
637 static constexpr std::size_t
kSize =
sizeof(std::uint32_t);
638 static constexpr std::size_t kBitsOnStorage =
kSize * 8;
640 bool IsMappable() const final {
return kIsMappable; }
645class RColumnElement<std::int64_t,
EColumnType::kInt64> :
public RColumnElementLE<std::int64_t> {
647 static constexpr std::size_t
kSize =
sizeof(std::int64_t);
648 static constexpr std::size_t kBitsOnStorage =
kSize * 8;
650 bool IsMappable() const final {
return kIsMappable; }
656 :
public RColumnElementSplitLE<std::int64_t, std::int64_t> {
658 static constexpr std::size_t
kSize =
sizeof(std::int64_t);
659 static constexpr std::size_t kBitsOnStorage =
kSize * 8;
661 bool IsMappable() const final {
return kIsMappable; }
666class RColumnElement<std::int64_t,
EColumnType::kInt32> :
public RColumnElementCastLE<std::int64_t, std::int32_t> {
668 static constexpr std::size_t
kSize =
sizeof(std::int64_t);
669 static constexpr std::size_t kBitsOnStorage = 32;
671 bool IsMappable() const final {
return kIsMappable; }
677 :
public RColumnElementSplitLE<std::int64_t, std::int32_t> {
679 static constexpr std::size_t
kSize =
sizeof(std::int64_t);
680 static constexpr std::size_t kBitsOnStorage = 32;
682 bool IsMappable() const final {
return kIsMappable; }
687class RColumnElement<std::uint64_t,
EColumnType::kInt64> :
public RColumnElementLE<std::uint64_t> {
689 static constexpr std::size_t
kSize =
sizeof(std::uint64_t);
690 static constexpr std::size_t kBitsOnStorage =
kSize * 8;
692 bool IsMappable() const final {
return kIsMappable; }
698 :
public RColumnElementSplitLE<std::uint64_t, std::uint64_t> {
700 static constexpr std::size_t
kSize =
sizeof(std::uint64_t);
701 static constexpr std::size_t kBitsOnStorage =
kSize * 8;
703 bool IsMappable() const final {
return kIsMappable; }
710 static constexpr std::size_t
kSize =
sizeof(float);
711 static constexpr std::size_t kBitsOnStorage =
kSize * 8;
720 static constexpr std::size_t
kSize =
sizeof(float);
721 static constexpr std::size_t kBitsOnStorage =
kSize * 8;
731 static constexpr std::size_t kBitsOnStorage =
kSize * 8;
741 static constexpr std::size_t kBitsOnStorage =
kSize * 8;
751 static constexpr std::size_t kBitsOnStorage = 64;
761 static constexpr std::size_t kBitsOnStorage = 32;
772 static constexpr std::size_t kBitsOnStorage = 64;
783 static constexpr std::size_t kBitsOnStorage = 32;
792 static constexpr bool kIsMappable =
false;
794 static constexpr std::size_t kBitsOnStorage = 64;
799 void Pack(
void *dst,
void *
src, std::size_t count)
const final
802 auto uint64Array =
reinterpret_cast<std::uint64_t *
>(dst);
803 for (std::size_t i = 0; i < count; ++i) {
805 (
static_cast<std::uint64_t
>(srcArray[i].GetTag()) << 44) | (srcArray[i].GetIndex() & 0x0fffffffffff);
806#if R__LITTLE_ENDIAN == 0
812 void Unpack(
void *dst,
void *
src, std::size_t count)
const final
814 auto uint64Array =
reinterpret_cast<std::uint64_t *
>(
src);
816 for (std::size_t i = 0; i < count; ++i) {
817#if R__LITTLE_ENDIAN == 1
818 const auto value = uint64Array[i];
828template <
typename CppT>
832 case EColumnType::kIndex64:
return std::make_unique<RColumnElement<CppT, EColumnType::kIndex64>>(
nullptr);
833 case EColumnType::kIndex32:
return std::make_unique<RColumnElement<CppT, EColumnType::kIndex32>>(
nullptr);
834 case EColumnType::kSwitch:
return std::make_unique<RColumnElement<CppT, EColumnType::kSwitch>>(
nullptr);
835 case EColumnType::kByte:
return std::make_unique<RColumnElement<CppT, EColumnType::kByte>>(
nullptr);
836 case EColumnType::kChar:
return std::make_unique<RColumnElement<CppT, EColumnType::kChar>>(
nullptr);
837 case EColumnType::kBit:
return std::make_unique<RColumnElement<CppT, EColumnType::kBit>>(
nullptr);
838 case EColumnType::kReal64:
return std::make_unique<RColumnElement<CppT, EColumnType::kReal64>>(
nullptr);
839 case EColumnType::kReal32:
return std::make_unique<RColumnElement<CppT, EColumnType::kReal32>>(
nullptr);
840 case EColumnType::kInt64:
return std::make_unique<RColumnElement<CppT, EColumnType::kInt64>>(
nullptr);
841 case EColumnType::kInt32:
return std::make_unique<RColumnElement<CppT, EColumnType::kInt32>>(
nullptr);
842 case EColumnType::kInt16:
return std::make_unique<RColumnElement<CppT, EColumnType::kInt16>>(
nullptr);
843 case EColumnType::kInt8:
return std::make_unique<RColumnElement<CppT, EColumnType::kInt8>>(
nullptr);
858std::unique_ptr<RColumnElementBase> RColumnElementBase::Generate<void>(
EColumnType type);
#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
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-...
void WriteTo(void *destination, std::size_t count) const
Write one or multiple column elements into destination.
RColumnElementBase(RColumnElementBase &&other)=default
virtual bool IsMappable() const
Derived, typed classes tell whether the on-storage layout is bitwise identical to the memory layout.
void * fRawContent
Points to valid C++ data, either a single value or an array of values.
RColumnElementBase(void *rawContent, std::size_t size)
void * GetRawContent() const
virtual std::size_t GetBitsOnStorage() const
RColumnElementBase(const RColumnElementBase &other)=default
RColumnElementBase & operator=(const RColumnElementBase &other)=delete
std::size_t fSize
Size of the C++ value pointed to by fRawContent (not necessarily equal to the on-disk element size)
static std::string GetTypeName(EColumnType type)
void ReadFrom(void *source, std::size_t count)
Set the column element or an array of elements from the memory location source.
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(const RColumnElementBase &elemArray, std::size_t at)
std::size_t GetPackedSize(std::size_t nElements) const
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
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-...
RColumnElementCastLE(void *rawContent, std::size_t size)
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-...
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-...
RColumnElementDeltaSplitLE(void *rawContent, std::size_t size)
static constexpr bool kIsMappable
Base class for columns whose on-storage representation is little-endian.
RColumnElementLE(void *rawContent, 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(void *rawContent, 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-...
RColumnElement(ClusterSize_t *value)
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.
bool IsMappable() const final
Derived, typed classes tell whether the on-storage layout is bitwise identical to the memory layout.
RColumnElement(ClusterSize_t *value)
std::size_t GetBitsOnStorage() const final
RColumnElement(ClusterSize_t *value)
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.
RColumnElement(ClusterSize_t *value)
bool IsMappable() const final
Derived, typed classes tell whether the on-storage layout is bitwise identical to the memory layout.
std::size_t GetBitsOnStorage() const final
RColumnElement(ClusterSize_t *value)
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-...
RColumnElement(RColumnSwitch *value)
std::size_t GetBitsOnStorage() const final
RColumnElement(RColumnSwitch *value)
RColumnElement(bool *value)
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.
RColumnElement(bool *value)
std::size_t GetBitsOnStorage() const final
RColumnElement(char *value)
bool IsMappable() const final
Derived, typed classes tell whether the on-storage layout is bitwise identical to the memory layout.
bool IsMappable() const final
Derived, typed classes tell whether the on-storage layout is bitwise identical to the memory layout.
std::size_t GetBitsOnStorage() const final
RColumnElement(char *value)
RColumnElement(char *value)
std::size_t GetBitsOnStorage() const final
RColumnElement(double *value)
bool IsMappable() const final
Derived, typed classes tell whether the on-storage layout is bitwise identical to the memory layout.
bool IsMappable() const final
Derived, typed classes tell whether the on-storage layout is bitwise identical to the memory layout.
std::size_t GetBitsOnStorage() const final
RColumnElement(double *value)
RColumnElement(double *value)
bool IsMappable() const final
Derived, typed classes tell whether the on-storage layout is bitwise identical to the memory layout.
std::size_t GetBitsOnStorage() const final
RColumnElement(float *value)
RColumnElement(float *value)
bool IsMappable() const final
Derived, typed classes tell whether the on-storage layout is bitwise identical to the memory layout.
std::size_t GetBitsOnStorage() const final
RColumnElement(float *value)
A column element points either to the content of an RFieldValue or into a memory mapped page.
RColumnElement(CppT *value)
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.