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
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#ifndef INCLUDED_IXION_DETAIL_UTILS_HPP
#define INCLUDED_IXION_DETAIL_UTILS_HPP
#include "ixion/types.hpp"
#include "column_store_type.hpp"
#include <sstream>
namespace ixion { namespace detail {
celltype_t to_celltype(mdds::mtv::element_t mtv_type);
cell_value_t to_cell_value_type(
const column_store_t::const_position_type& pos, formula_result_wait_policy_t policy);
template<std::size_t S, typename T>
void ensure_max_size(const T& v)
{
static_assert(sizeof(T) <= S, "The size of the value exceeded allowed size limit.");
}
template<typename T>
class const_element_block_range
{
const T* m_begin;
const T* m_end;
public:
const_element_block_range(const T* begin, const T* end) : m_begin(begin), m_end(end) {}
const T* begin() const { return m_begin; }
const T* end() const { return m_end; }
};
/* Specialization for bool in order to handle std::vector<bool>. */
template<>
class const_element_block_range<bool>
{
using iterator_type = boolean_element_block::const_iterator;
iterator_type m_begin;
iterator_type m_end;
public:
const_element_block_range(const iterator_type& begin, const iterator_type& end) :
m_begin(begin), m_end(end) {}
iterator_type begin() const { return m_begin; }
iterator_type end() const { return m_end; }
};
template<column_block_t BlockT>
struct make_element_range;
template<>
struct make_element_range<column_block_t::boolean>
{
const_element_block_range<bool> operator()(const column_block_shape_t& node, std::size_t length) const
{
// NB: special treatment for std::vector<bool> which underlies boolean_element_block.
const auto* blk = reinterpret_cast<const boolean_element_block*>(node.data);
auto it = boolean_element_block::cbegin(*blk);
it = std::next(it, node.offset);
length = std::min(node.size - node.offset, length);
auto it_end = std::next(it, length);
return {it, it_end};
}
};
template<>
struct make_element_range<column_block_t::numeric>
{
const_element_block_range<double> operator()(const column_block_shape_t& node, std::size_t length) const
{
const auto* blk = reinterpret_cast<const numeric_element_block*>(node.data);
const double* p = &numeric_element_block::at(*blk, node.offset);
length = std::min(node.size - node.offset, length);
const double* p_end = p + length;
return {p, p_end};
}
};
template<>
struct make_element_range<column_block_t::formula>
{
const_element_block_range<const formula_cell*> operator()(const column_block_shape_t& node, std::size_t length) const
{
const auto* blk = reinterpret_cast<const formula_element_block*>(node.data);
auto p = &formula_element_block::at(*blk, node.offset);
length = std::min(node.size - node.offset, length);
auto p_end = p + length;
return {p, p_end};
}
};
// TODO : add specialization for the other block types as needed.
}}
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|