summaryrefslogtreecommitdiff
path: root/modules/codec/c++/forst.tmpl.hpp
blob: 1dc0ac13d1dfe0cf58e6e93f3e1e1c4a08b92595 (plain)
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
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
namespace saw {
namespace impl {

/**
 * This class provides basic info on sizes of the encode::Forst 
 */
template<typename Schema>
struct forst_codec_info {
	static_assert(always_false<Schema>, "Not supported.");
};

template<typename T, uint64_t N>
struct forst_codec_info<schema::Primitive<T,N>> {
public:
	static constexpr uint64_t layers = 0u;

	static constexpr uint64_t static_size = N;
	
	template<typename Encoding>
	static uint64_t dynamic_size(const data<schema::Primitive<T,N>, Encoding>&) noexcept {
		return 0u;
	}
};

template<>
struct forst_codec_info<schema::String> {
public:
	static constexpr uint64_t layers = 1u;
	
	static constexpr uint64_t static_size = forst_codec_info<typename meta_schema<schema::String>::MetaSchema>::static_size;

	template<typename Encoding>
	static uint64_t dynamic_size (const data<schema::String, Encoding>& dat) noexcept {
		return dat.size() * 1u;
	}
};

template<typename T, uint64_t N>
struct forst_codec_info<schema::Array<T,N>> {
public:
	static constexpr uint64_t layers = 1u + forst_codec_info<T>::layers;

	/// Dimension and the relative pointer
	static constexpr uint64_t static_size = 8u * N + 8u;
	
	template<typename Encoding>
	static uint64_t dynamic_size (const data<schema::String, Encoding>& dat) {
		return dat.size() * forst_codec_info<T>::static_size;
	}
};

template<typename... Members>
struct forst_codec_info<schema::Struct<Members...> > {
public:
	template<uint64_t i>
	static constexpr uint64_t max_layers() noexcept {
		if constexpr ( i < sizeof...(Members) ) {
			using MT = typename parameter_pack_type<i, Members...>::type;

			constexpr uint64_t layer_i = forst_codec_info<typename MT::ValueType>::layers;

			constexpr uint64_t layer_next = max_layers<i+1u>();

			constexpr uint64_t layer_val = layer_i > layer_next ? layer_i : layer_next;

			return layer_val;
		}
		return 0u;
	}

public:
	static constexpr uint64_t layers = max_layers<0u>();

public:
	template<uint64_t i>
	static constexpr uint64_t static_size_calc(){
		if constexpr ( i < sizeof...(Members) ) {
			using MT = typename parameter_pack_type<i, Members...>::type;

			constexpr uint64_t layer_i = forst_codec_info<typename MT::ValueType>::static_size + static_size_calc<i+1u>();
			return layer_i;
		}
		return 0u;
	}
	
public:
	static constexpr uint64_t static_size = static_size_calc<0>();

	template<typename Encoding, uint64_t i>
	static uint64_t dynamic_size_calc(const data<schema::Struct<Members...>, Encoding>& dat) noexcept {
		if constexpr ( i < sizeof...(Members) ){
			using MT = typename parameter_pack_type<i, Members...>::type;

			constexpr uint64_t layer_i = forst_codec_info<typename MT::ValueType>::dynamic_size(dat) + dynamic_size_calc<i+1u>(dat);
			return layer_i;
		}
		return 0u;
	}
public:
	template<typename Encoding>
	static uint64_t dynamic_size(const data<schema::Struct<Members...>, Encoding>& dat) noexcept {
		return dynamic_size_calc<0u>(dat);
	}
};

template<typename... T>
struct forst_codec_info<schema::Tuple<T...>> {
public:
	template<uint64_t i>
	static constexpr uint64_t max_layers() noexcept {
		if constexpr ( i < sizeof...(T) ) {
			using MT = typename parameter_pack_type<i, T...>::type;

			constexpr uint64_t layer_i = forst_codec_info<MT>::layers;

			constexpr uint64_t layer_next = max_layers<i+1u>();

			constexpr uint64_t layer_val = layer_i > layer_next ? layer_i : layer_next;

			return layer_val;
		}
		return 0u;
	}
public:
	static constexpr uint64_t layers = max_layers<0u>();
public:
	template<uint64_t i>
	static constexpr uint64_t static_size_calc(){
		if constexpr ( i < sizeof...(T) ) {
			using MT = typename parameter_pack_type<i, T...>::type;

			constexpr uint64_t layer_i = forst_codec_info<MT>::static_size + layer_size_calc<i+1u>();
		}
		return 0u;
	}
	
public:
	static constexpr uint64_t static_size = static_size_calc<0>();

	template<typename Encoding, uint64_t i>
	static uint64_t dynamic_size_calc(const data<schema::Tuple<T...>, Encoding>& dat) noexcept {
		if constexpr ( i < sizeof...(T) ){
			using MT = typename parameter_pack_type<i, T...>::type;

			constexpr uint64_t layer_i = forst_codec_info<MT>::dynamic_size(dat) + dynamic_size_calc<i+1u>(dat);
			return layer_i;
		}
		return 0u;
	}
public:
	template<typename Encoding>
	static uint64_t dynamic_size(const data<schema::Tuple<T...>, Encoding>& dat) noexcept {
		return dynamic_size_calc<0u>(dat);
	}
};
}
}