mdds
util.hpp
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*************************************************************************
3 *
4 * Copyright (c) 2021 Kohei Yoshida
5 *
6 * Permission is hereby granted, free of charge, to any person
7 * obtaining a copy of this software and associated documentation
8 * files (the "Software"), to deal in the Software without
9 * restriction, including without limitation the rights to use,
10 * copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following
13 * conditions:
14 *
15 * The above copyright notice and this permission notice shall be
16 * included in all copies or substantial portions of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
20 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
22 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
23 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
24 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25 * OTHER DEALINGS IN THE SOFTWARE.
26 *
27 ************************************************************************/
28
29#ifndef INCLUDED_MDDS_MULTI_TYPE_VECTOR_DIR_UTIL_HPP
30#define INCLUDED_MDDS_MULTI_TYPE_VECTOR_DIR_UTIL_HPP
31
32#include "./block_funcs.hpp"
33
34#include <sstream>
35
36namespace mdds { namespace mtv {
37
43{
53 {
54 (void)block;
55 }
56
66 {
67 (void)block;
68 }
69};
70
75{
81
86 static constexpr lu_factor_t loop_unrolling = lu_factor_t::lu16;
87
97};
98
99namespace detail {
100
101#ifdef MDDS_MULTI_TYPE_VECTOR_DEBUG
102
103template<typename T, typename = void>
104struct has_trace : std::false_type
105{
106};
107
108template<typename T>
109struct has_trace<T, decltype((void)T::trace)> : std::true_type
110{
111};
112
113template<typename Traits>
114struct call_trace
115{
116 int& call_depth;
117
118 call_trace(int& _call_depth) : call_depth(_call_depth)
119 {
120 ++call_depth;
121 }
122 ~call_trace() noexcept
123 {
124 --call_depth;
125 }
126
127 void call(std::false_type, const ::mdds::mtv::trace_method_properties_t&) const
128 {
129 // sink
130 }
131
132 void call(std::true_type, const ::mdds::mtv::trace_method_properties_t& props) const
133 {
134 // In case of recursive calls, only trace the first encountered method.
135 if (call_depth <= 1)
136 Traits::trace(props);
137 }
138
139 void operator()(const ::mdds::mtv::trace_method_properties_t& props) const
140 {
141 call(has_trace<Traits>{}, props);
142 }
143};
144
145#endif
146
147inline void throw_block_position_not_found(
148 const char* method_sig, int line, size_t pos, size_t block_size, size_t container_size)
149{
150 std::ostringstream os;
151 os << method_sig << "#" << line << ": block position not found! (logical pos=" << pos
152 << ", block size=" << block_size << ", logical size=" << container_size << ")";
153 throw std::out_of_range(os.str());
154}
155
174template<typename _T, typename _SizeT>
175std::pair<_SizeT, bool> calc_input_end_position(const _T& it_begin, const _T& it_end, _SizeT pos, _SizeT total_size)
176{
177 using ret_type = std::pair<_SizeT, bool>;
178
179 _SizeT length = std::distance(it_begin, it_end);
180 if (!length)
181 // empty data array. nothing to do.
182 return ret_type(0, false);
183
184 _SizeT end_pos = pos + length - 1;
185 if (end_pos >= total_size)
186 throw std::out_of_range("Input data sequence is too long.");
187
188 return ret_type(end_pos, true);
189}
190
191template<typename T>
192T advance_position(const T& pos, int steps)
193{
194 T ret = pos;
195
196 if (steps > 0)
197 {
198 while (steps > 0)
199 {
200 if (ret.second + steps < ret.first->size)
201 {
202 // element is still in the same block.
203 ret.second += steps;
204 break;
205 }
206 else
207 {
208 steps -= static_cast<int>(ret.first->size - ret.second);
209 ++ret.first;
210 ret.second = 0;
211 }
212 }
213 }
214 else
215 {
216 while (steps < 0)
217 {
218 if (static_cast<int>(ret.second) >= -steps)
219 {
220 ret.second += steps;
221 break;
222 }
223 else
224 {
225 steps += static_cast<int>(ret.second + 1);
226 --ret.first;
227 ret.second = ret.first->size - 1;
228 }
229 }
230 }
231
232 return ret;
233}
234
235} // namespace detail
236
237}} // namespace mdds::mtv
238
239#ifdef MDDS_MULTI_TYPE_VECTOR_DEBUG
240
241#define MDDS_MTV_TRACE(method_type) \
242 ::mdds::mtv::detail::call_trace<Traits> mdds_mtv_ct(m_trace_call_depth); \
243 mdds_mtv_ct({trace_method_t::method_type, this, __func__, "", __FILE__, __LINE__})
244
245#define MDDS_MTV_TRACE_ARGS(method_type, stream) \
246 ::mdds::mtv::detail::call_trace<Traits> mdds_mtv_ct(m_trace_call_depth); \
247 do \
248 { \
249 std::ostringstream _os_; \
250 _os_ << stream; \
251 mdds_mtv_ct({trace_method_t::method_type, this, __func__, _os_.str(), __FILE__, __LINE__}); \
252 } while (false)
253
254#else
255
256#define MDDS_MTV_TRACE(...)
257
258#define MDDS_MTV_TRACE_ARGS(...)
259
260#endif
261
262#endif
263
264/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Definition: types.hpp:160
Definition: util.hpp:75
static constexpr lu_factor_t loop_unrolling
Definition: util.hpp:86
Definition: block_funcs.hpp:65
Definition: util.hpp:43
void element_block_acquired(const base_element_block *block)
Definition: util.hpp:52
void element_block_released(const base_element_block *block)
Definition: util.hpp:65