Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RColumnElementBase.hxx
Go to the documentation of this file.
1/// \file ROOT/RColumnElementBase.hxx
2/// \ingroup NTuple ROOT7
3/// \author Jakob Blomer <jblomer@cern.ch>
4/// \date 2018-10-09
5/// \warning This is part of the ROOT 7 prototype! It will change without notice. It might trigger earthquakes. Feedback
6/// is welcome!
7
8/*************************************************************************
9 * Copyright (C) 1995-2019, Rene Brun and Fons Rademakers. *
10 * All rights reserved. *
11 * *
12 * For the licensing terms see $ROOTSYS/LICENSE. *
13 * For the list of contributors see $ROOTSYS/README/CREDITS. *
14 *************************************************************************/
15
16#ifndef ROOT7_RColumnElementBase
17#define ROOT7_RColumnElementBase
18
19#include "RtypesCore.h"
20#include <ROOT/RError.hxx>
21#include <ROOT/RFloat16.hxx>
22#include <ROOT/RNTupleUtil.hxx>
23
24#include <Byteswap.h>
25#include <TError.h>
26
27#include <cstring> // for memcpy
28#include <cstddef> // for std::byte
29#include <cstdint>
30#include <memory>
31#include <optional>
32#include <string>
33#include <type_traits>
34#include <typeinfo>
35#include <utility>
36
38
39// clang-format off
40/**
41\class ROOT::Experimental::Internal::RColumnElementBase
42\ingroup NTuple
43\brief A column element encapsulates the translation between basic C++ types and their column representation.
44
45Usually the on-disk element should map bitwise to the in-memory element. Sometimes that's not the case
46though, for instance on big endian platforms or for bools.
47
48There is a template specialization for every valid pair of C++ type and column representation.
49These specialized child classes are responsible for overriding `Pack()` / `Unpack()` for packing / unpacking elements
50as appropriate.
51*/
52// clang-format on
54protected:
55 /// Size of the C++ value that corresponds to the on-disk element
56 std::size_t fSize;
57 std::size_t fBitsOnStorage;
58 /// This is only meaningful for column elements that support it (e.g. Real32Quant)
59 std::optional<std::pair<double, double>> fValueRange = std::nullopt;
60
61 explicit RColumnElementBase(std::size_t size, std::size_t bitsOnStorage = 0)
62 : fSize(size), fBitsOnStorage(bitsOnStorage ? bitsOnStorage : 8 * size)
63 {
64 }
65
66public:
67 RColumnElementBase(const RColumnElementBase &other) = default;
71 virtual ~RColumnElementBase() = default;
72
73 /// If CppT == void, use the default C++ type for the given column type
74 template <typename CppT = void>
75 static std::unique_ptr<RColumnElementBase> Generate(EColumnType type);
76 static std::string GetTypeName(EColumnType type);
77 /// Most types have a fixed on-disk bit width. Some low-precision column types
78 /// have a range of possible bit widths. Return the minimum and maximum allowed
79 /// bit size per type.
80 static std::pair<std::uint16_t, std::uint16_t> GetValidBitRange(EColumnType type);
81
82 /// Derived, typed classes tell whether the on-storage layout is bitwise identical to the memory layout
83 virtual bool IsMappable() const
84 {
85 R__ASSERT(false);
86 return false;
87 }
88
89 virtual void SetBitsOnStorage(std::size_t bitsOnStorage)
90 {
91 if (bitsOnStorage != fBitsOnStorage)
92 throw RException(R__FAIL(std::string("internal error: cannot change bit width of this column type")));
93 }
94
95 virtual void SetValueRange(double, double)
96 {
97 throw RException(R__FAIL(std::string("internal error: cannot change value range of this column type")));
98 }
99
100 /// If the on-storage layout and the in-memory layout differ, packing creates an on-disk page from an in-memory page
101 virtual void Pack(void *destination, const void *source, std::size_t count) const
102 {
103 std::memcpy(destination, source, count);
104 }
105
106 /// If the on-storage layout and the in-memory layout differ, unpacking creates a memory page from an on-storage page
107 virtual void Unpack(void *destination, const void *source, std::size_t count) const
108 {
109 std::memcpy(destination, source, count);
110 }
111
112 std::size_t GetSize() const { return fSize; }
113 std::size_t GetBitsOnStorage() const { return fBitsOnStorage; }
114 std::optional<std::pair<double, double>> GetValueRange() const { return fValueRange; }
115 std::size_t GetPackedSize(std::size_t nElements = 1U) const { return (nElements * fBitsOnStorage + 7) / 8; }
116}; // class RColumnElementBase
117
118// All supported C++ in-memory types
119enum class EColumnCppType {
120 kChar,
121 kBool,
122 kByte,
123 kUint8,
124 kUint16,
125 kUint32,
126 kUint64,
127 kInt8,
128 kInt16,
129 kInt32,
130 kInt64,
131 kFloat,
132 kDouble,
135 kMax
136};
137
139 static_cast<EColumnCppType>(std::numeric_limits<std::underlying_type_t<EColumnCppType>>::max() - 1);
140
142 std::uint32_t dummy;
143};
144
145std::unique_ptr<RColumnElementBase> GenerateColumnElement(EColumnCppType cppType, EColumnType colType);
146
147template <typename CppT>
148std::unique_ptr<RColumnElementBase> RColumnElementBase::Generate(EColumnType type)
149{
150 if constexpr (std::is_same_v<CppT, char>)
152 else if constexpr (std::is_same_v<CppT, bool>)
154 else if constexpr (std::is_same_v<CppT, std::byte>)
156 else if constexpr (std::is_same_v<CppT, std::uint8_t>)
158 else if constexpr (std::is_same_v<CppT, std::uint16_t>)
160 else if constexpr (std::is_same_v<CppT, std::uint32_t>)
162 else if constexpr (std::is_same_v<CppT, std::uint64_t>)
164 else if constexpr (std::is_same_v<CppT, std::int8_t>)
166 else if constexpr (std::is_same_v<CppT, std::int16_t>)
168 else if constexpr (std::is_same_v<CppT, std::int32_t>)
170 else if constexpr (std::is_same_v<CppT, std::int64_t>)
172 else if constexpr (std::is_same_v<CppT, float>)
174 else if constexpr (std::is_same_v<CppT, double>)
176 else if constexpr (std::is_same_v<CppT, ClusterSize_t>)
178 else if constexpr (std::is_same_v<CppT, RColumnSwitch>)
180 else if constexpr (std::is_same_v<CppT, RTestFutureColumn>)
182 else
183 static_assert(!sizeof(CppT), "Unsupported Cpp type");
184}
185
186template <>
187std::unique_ptr<RColumnElementBase> RColumnElementBase::Generate<void>(EColumnType type);
188
189} // namespace ROOT::Experimental::Internal
190
191#endif
#define R__FAIL(msg)
Short-hand to return an RResult<T> in an error state; the RError is implicitly converted into RResult...
Definition RError.hxx:290
size_t size(const MatrixT &matrix)
retrieve the size of a square matrix
#define R__ASSERT(e)
Checks condition e and reports a fatal error if it's false.
Definition TError.h:125
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
RColumnElementBase(std::size_t size, std::size_t bitsOnStorage=0)
virtual bool IsMappable() const
Derived, typed classes tell whether the on-storage layout is bitwise identical to the memory layout.
std::optional< std::pair< double, double > > fValueRange
This is only meaningful for column elements that support it (e.g. Real32Quant)
virtual void Pack(void *destination, const 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-...
static std::string GetTypeName(EColumnType type)
std::size_t fSize
Size of the C++ value that corresponds to the on-disk element.
std::optional< std::pair< double, double > > GetValueRange() const
RColumnElementBase(const RColumnElementBase &other)=default
RColumnElementBase & operator=(RColumnElementBase &&other)=default
virtual void Unpack(void *destination, const 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 void SetBitsOnStorage(std::size_t bitsOnStorage)
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
static std::pair< std::uint16_t, std::uint16_t > GetValidBitRange(EColumnType type)
Most types have a fixed on-disk bit width.
RColumnElementBase(RColumnElementBase &&other)=default
Base class for all ROOT issued exceptions.
Definition RError.hxx:78
constexpr EColumnCppType kTestFutureColumn
std::unique_ptr< RColumnElementBase > GenerateColumnElement(EColumnCppType cppType, EColumnType colType)