-
Notifications
You must be signed in to change notification settings - Fork 199
Expand file tree
/
Copy pathitemview.h
More file actions
86 lines (72 loc) · 2.72 KB
/
itemview.h
File metadata and controls
86 lines (72 loc) · 2.72 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
#pragma once
#include "../types/types.h"
#include "../exceptions.h"
#include <string_view>
#include <stdexcept>
#include <type_traits>
namespace clickhouse {
/** ItemView is a view on a data stored in Column, safe-ish interface for reading values from Column.
*
* Data is not owned (hence the name View) and will be invalidated on column update, load
* or destruction (basically on calling any non-const method of Column).
* `type` reflects what is stored in `data` and can be almost any value-type
* (except Nullable, Array, Tuple, LowCardinality).
*
*/
struct ItemView {
using DataType = std::string_view;
const Type::Code type;
const DataType data;
private:
template <typename T>
inline auto ConvertToStorageValue(const T& t) {
if constexpr (std::is_same_v<std::string_view, T> || std::is_same_v<std::string, T>) {
return std::string_view{t};
} else if constexpr (std::is_fundamental_v<T> || std::is_same_v<Int128, std::decay_t<T>> || std::is_same_v<UInt128, std::decay_t<T>>) {
return std::string_view{reinterpret_cast<const char*>(&t), sizeof(T)};
} else {
static_assert(!std::is_same_v<T, T>, "Unknown type, which can't be stored in ItemView");
return;
}
}
public:
ItemView(Type::Code type, DataType data)
: type(type),
data(data)
{
ValidateData(type, data);
}
ItemView(Type::Code type, ItemView other)
: type(type),
data(other.data)
{
ValidateData(type, data);
}
explicit ItemView()
: ItemView(Type::Void, std::string_view{})
{}
template <typename T>
explicit ItemView(Type::Code type, const T & value)
: ItemView(type, ConvertToStorageValue(value))
{}
template <typename T>
auto get() const {
using ValueType = std::remove_cv_t<std::decay_t<T>>;
if constexpr (std::is_same_v<std::string_view, ValueType> || std::is_same_v<std::string, ValueType>) {
return data;
} else if constexpr (std::is_fundamental_v<ValueType> || std::is_same_v<Int128, ValueType> || std::is_same_v<UInt128, ValueType>) {
if (sizeof(ValueType) == data.size()) {
return *reinterpret_cast<const T*>(data.data());
} else {
throw AssertionError("Incompatible value type and size. Requested size: "
+ std::to_string(sizeof(ValueType)) + " stored size: " + std::to_string(data.size()));
}
}
}
inline std::string_view AsBinaryData() const {
return data;
}
// Validate that value matches type, will throw an exception if validation fails.
static void ValidateData(Type::Code type, DataType data);
};
}