Orcus
Loading...
Searching...
No Matches
pivot.hpp
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
6 */
7
8#ifndef INCLUDED_ORCUS_SPREADSHEET_PIVOT_HPP
9#define INCLUDED_ORCUS_SPREADSHEET_PIVOT_HPP
10
11#include "../env.hpp"
12#include "../types.hpp"
13#include "types.hpp"
14
15#include <memory>
16#include <vector>
17#include <limits>
18#include <variant>
19#include <optional>
20#include <ostream>
21
22namespace ixion {
23
24struct abs_range_t;
25struct abs_rc_range_t;
26
27}
28
29namespace orcus {
30
31class string_pool;
32
33namespace spreadsheet {
34
35class document;
37
38namespace detail {
39
40class debug_state_dumper_pivot_cache;
41class debug_state_dumper_pivot_table;
42
43}
44
45using pivot_cache_indices_t = std::vector<size_t>;
46
47struct ORCUS_SPM_DLLPUBLIC pivot_cache_record_value_t
48{
49 using value_type = std::variant<bool, double, std::size_t, std::string_view, date_time_t, error_value_t>;
50
51 enum class record_type
52 {
53 unknown = 0,
54 boolean,
55 date_time,
56 character,
57 numeric,
58 blank,
59 error,
60 shared_item_index
61 };
62
63 record_type type;
64 value_type value;
65
66 pivot_cache_record_value_t();
67 pivot_cache_record_value_t(std::string_view s);
68 pivot_cache_record_value_t(double v);
69 pivot_cache_record_value_t(size_t index);
70
71 bool operator== (const pivot_cache_record_value_t& other) const;
72 bool operator!= (const pivot_cache_record_value_t& other) const;
73};
74
75using pivot_cache_record_t = std::vector<pivot_cache_record_value_t>;
76
77struct ORCUS_SPM_DLLPUBLIC pivot_cache_item_t
78{
79 using value_type = std::variant<bool, double, std::string_view, date_time_t, error_value_t>;
80
81 enum class item_type
82 {
83 unknown = 0, boolean, date_time, character, numeric, blank, error
84 };
85
86 item_type type;
87 value_type value;
88
89 pivot_cache_item_t();
90 pivot_cache_item_t(std::string_view s);
91 pivot_cache_item_t(double numeric);
92 pivot_cache_item_t(bool boolean);
93 pivot_cache_item_t(const date_time_t& date_time);
94 pivot_cache_item_t(error_value_t error);
95
96 pivot_cache_item_t(const pivot_cache_item_t& other);
97 pivot_cache_item_t(pivot_cache_item_t&& other);
98
99 bool operator< (const pivot_cache_item_t& other) const;
100 bool operator== (const pivot_cache_item_t& other) const;
101
102 pivot_cache_item_t& operator= (pivot_cache_item_t other);
103
104 void swap(pivot_cache_item_t& other);
105};
106
107using pivot_cache_items_t = std::vector<pivot_cache_item_t>;
108
112struct ORCUS_SPM_DLLPUBLIC pivot_cache_group_data_t
113{
114 struct ORCUS_SPM_DLLPUBLIC range_grouping_type
115 {
116 pivot_cache_group_by_t group_by = pivot_cache_group_by_t::range;
117
118 bool auto_start = true;
119 bool auto_end = true;
120
121 double start = 0.0;
122 double end = 0.0;
123 double interval = 1.0;
124
125 date_time_t start_date;
126 date_time_t end_date;
127
128 range_grouping_type();
129 range_grouping_type(const range_grouping_type& other);
130 };
131
135 pivot_cache_indices_t base_to_group_indices;
136
137 std::optional<range_grouping_type> range_grouping;
138
142 pivot_cache_items_t items;
143
146
147 pivot_cache_group_data_t(size_t _base_field);
148 pivot_cache_group_data_t(const pivot_cache_group_data_t& other);
149 pivot_cache_group_data_t(pivot_cache_group_data_t&& other);
150
151 pivot_cache_group_data_t() = delete;
152};
153
154struct ORCUS_SPM_DLLPUBLIC pivot_cache_field_t
155{
160 std::string_view name;
161
162 pivot_cache_items_t items;
163
164 std::optional<double> min_value;
165 std::optional<double> max_value;
166
167 std::optional<date_time_t> min_date;
168 std::optional<date_time_t> max_date;
169
170 std::unique_ptr<pivot_cache_group_data_t> group_data;
171
172 pivot_cache_field_t();
173 pivot_cache_field_t(std::string_view _name);
174 pivot_cache_field_t(const pivot_cache_field_t& other);
175 pivot_cache_field_t(pivot_cache_field_t&& other);
176
177 pivot_cache_field_t& operator=(pivot_cache_field_t other);
178
179 void swap(pivot_cache_field_t& other) noexcept;
180};
181
182struct ORCUS_SPM_DLLPUBLIC pivot_item_t
183{
184 using value_type = std::variant<std::size_t, pivot_field_item_t>;
185
186 enum class item_type
187 {
188 unknown = 0,
189 index,
190 type
191 };
192
193 item_type type;
194 value_type value;
195 bool hidden = false;
196
197 pivot_item_t();
198 pivot_item_t(const pivot_item_t& other);
199 pivot_item_t(pivot_item_t&& other);
200 pivot_item_t(std::size_t i, bool _hidden);
201 pivot_item_t(pivot_field_item_t t);
202 ~pivot_item_t();
203
204 pivot_item_t& operator=(pivot_item_t other);
205
206 void swap(pivot_item_t& other) noexcept;
207};
208
209using pivot_items_t = std::vector<pivot_item_t>;
210
211struct ORCUS_SPM_DLLPUBLIC pivot_field_t
212{
213 pivot_axis_t axis = pivot_axis_t::unknown;
214 pivot_items_t items;
215
216 pivot_field_t();
217 pivot_field_t(const pivot_field_t& other);
218 pivot_field_t(pivot_field_t&& other);
219 ~pivot_field_t();
220
221 pivot_field_t& operator=(pivot_field_t other);
222
223 void swap(pivot_field_t& other) noexcept;
224};
225
226using pivot_fields_t = std::vector<pivot_field_t>;
227
228struct ORCUS_SPM_DLLPUBLIC pivot_ref_rc_field_t
229{
230 enum class value_type { unknown = 0, index, data };
231
232 value_type type = value_type::unknown;
233 std::size_t index = 0;
234
235 pivot_ref_rc_field_t();
236 pivot_ref_rc_field_t(const pivot_ref_rc_field_t& other);
237 pivot_ref_rc_field_t(pivot_ref_rc_field_t&& other);
238 pivot_ref_rc_field_t(std::size_t _index);
239 pivot_ref_rc_field_t(value_type vt);
240 ~pivot_ref_rc_field_t();
241
242 pivot_ref_rc_field_t& operator=(pivot_ref_rc_field_t other);
243
244 void swap(pivot_ref_rc_field_t& other) noexcept;
245};
246
247using pivot_ref_rc_fields_t = std::vector<pivot_ref_rc_field_t>;
248
249struct ORCUS_SPM_DLLPUBLIC pivot_ref_page_field_t
250{
251 std::size_t field = 0;
252 std::optional<std::size_t> item;
253
254 pivot_ref_page_field_t();
255 pivot_ref_page_field_t(const pivot_ref_page_field_t& other);
256 pivot_ref_page_field_t(pivot_ref_page_field_t&& other);
257 ~pivot_ref_page_field_t();
258
259 pivot_ref_page_field_t& operator=(pivot_ref_page_field_t other);
260
261 void swap(pivot_ref_page_field_t& other) noexcept;
262};
263
264using pivot_ref_page_fields_t = std::vector<pivot_ref_page_field_t>;
265
266struct ORCUS_SPM_DLLPUBLIC pivot_ref_data_field_t
267{
268 std::size_t field = 0;
269 std::string_view name;
270 pivot_data_subtotal_t subtotal = pivot_data_subtotal_t::unknown;
271
272 pivot_data_show_data_as_t show_data_as = pivot_data_show_data_as_t::unknown;
273 std::size_t base_field = 0;
274 std::size_t base_item = 0;
275
276 pivot_ref_data_field_t();
277 pivot_ref_data_field_t(const pivot_ref_data_field_t& other);
278 pivot_ref_data_field_t(pivot_ref_data_field_t&& other);
279 ~pivot_ref_data_field_t();
280
281 pivot_ref_data_field_t& operator=(pivot_ref_data_field_t other);
282
283 void swap(pivot_ref_data_field_t& other) noexcept;
284};
285
286using pivot_ref_data_fields_t = std::vector<pivot_ref_data_field_t>;
287
294struct ORCUS_SPM_DLLPUBLIC pivot_ref_rc_item_t
295{
296 pivot_field_item_t type = pivot_field_item_t::unknown;
297
299 std::size_t repeat = 0;
300 std::vector<std::size_t> items;
301 std::optional<std::size_t> data_item;
302
303 pivot_ref_rc_item_t();
304 pivot_ref_rc_item_t(const pivot_ref_rc_item_t& other);
305 pivot_ref_rc_item_t(pivot_ref_rc_item_t&& other);
306 ~pivot_ref_rc_item_t();
307
308 pivot_ref_rc_item_t& operator=(pivot_ref_rc_item_t other);
309
310 void swap(pivot_ref_rc_item_t& other) noexcept;
311};
312
313using pivot_ref_rc_items_t = std::vector<pivot_ref_rc_item_t>;
314
315class ORCUS_SPM_DLLPUBLIC pivot_cache
316{
317 friend class detail::debug_state_dumper_pivot_cache;
318 friend class detail::debug_state_dumper_pivot_table;
319 friend class pivot_collection;
320
321 struct impl;
322 std::unique_ptr<impl> mp_impl;
323
324public:
325 using fields_type = std::vector<pivot_cache_field_t>;
326 using records_type = std::vector<pivot_cache_record_t>;
327
328 pivot_cache(pivot_cache_id_t cache_id, string_pool& sp);
329 ~pivot_cache();
330
337 void insert_fields(fields_type fields);
338
339 void insert_records(records_type record);
340
341 size_t get_field_count() const;
342
351 const pivot_cache_field_t* get_field(size_t index) const;
352
353 pivot_cache_id_t get_id() const;
354
355 const records_type& get_all_records() const;
356};
357
358class ORCUS_SPM_DLLPUBLIC pivot_table
359{
360 friend class detail::debug_state_dumper_pivot_table;
361 friend class pivot_collection;
362
363 struct impl;
364 std::unique_ptr<impl> mp_impl;
365
366public:
367 pivot_table(string_pool& pool);
368 pivot_table(const pivot_table&) = delete;
369 pivot_table(pivot_table&& other);
370 ~pivot_table();
371
372 pivot_table& operator=(const pivot_table&) = delete;
373 pivot_table& operator=(pivot_table&& other);
374
375 std::string_view get_name() const;
376 void set_name(std::string_view name);
377 void set_cache_id(pivot_cache_id_t cache_id);
378 void set_range(const ixion::abs_rc_range_t& range);
379 void set_pivot_fields(pivot_fields_t fields);
380 void set_row_fields(pivot_ref_rc_fields_t fields);
381 void set_column_fields(pivot_ref_rc_fields_t fields);
382 void set_page_fields(pivot_ref_page_fields_t fields);
383 void set_data_fields(pivot_ref_data_fields_t fields);
384 void set_row_items(pivot_ref_rc_items_t items);
385 void set_column_items(pivot_ref_rc_items_t items);
386};
387
388class ORCUS_SPM_DLLPUBLIC pivot_collection
389{
390 struct impl;
391 std::unique_ptr<impl> mp_impl;
392
393public:
394 pivot_collection(document& doc);
395 pivot_collection(const pivot_collection&) = delete;
396 ~pivot_collection();
397
407 std::string_view sheet_name, const ixion::abs_range_t& range, std::unique_ptr<pivot_cache>&& cache);
408
415 void insert_worksheet_cache(std::string_view table_name, std::unique_ptr<pivot_cache>&& cache);
416
417 void insert_pivot_table(pivot_table pt);
418
424 size_t get_cache_count() const;
425
426 const pivot_cache* get_cache(
427 std::string_view sheet_name, const ixion::abs_range_t& range) const;
428
429 pivot_cache* get_cache(pivot_cache_id_t cache_id);
430
431 const pivot_cache* get_cache(pivot_cache_id_t cache_id) const;
432
433 void dump_debug_state(std::string_view outdir) const;
434};
435
436ORCUS_SPM_DLLPUBLIC std::ostream& operator<<(std::ostream& os, const pivot_cache_item_t& item);
437ORCUS_SPM_DLLPUBLIC std::ostream& operator<<(std::ostream& os, const pivot_cache_record_value_t& v);
438ORCUS_SPM_DLLPUBLIC std::ostream& operator<<(std::ostream& os, const pivot_item_t& v);
439
440}}
441
442#endif
443
444/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Definition document.hpp:55
Definition pivot.hpp:316
const pivot_cache_field_t * get_field(size_t index) const
void insert_fields(fields_type fields)
Definition pivot.hpp:389
void insert_worksheet_cache(std::string_view sheet_name, const ixion::abs_range_t &range, std::unique_ptr< pivot_cache > &&cache)
void insert_worksheet_cache(std::string_view table_name, std::unique_ptr< pivot_cache > &&cache)
Definition pivot.hpp:359
Definition string_pool.hpp:26
Definition types.hpp:528
std::string_view name
Definition pivot.hpp:160
pivot_cache_indices_t base_to_group_indices
Definition pivot.hpp:135
pivot_cache_items_t items
Definition pivot.hpp:142
size_t base_field
Definition pivot.hpp:145
Definition pivot.hpp:183
std::size_t repeat
Definition pivot.hpp:299