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 "./types.hpp"
33 
34 #include <sstream>
35 
36 namespace mdds {
37 
38 namespace mtv {
39 
45 {
55  {
56  (void)block;
57  }
58 
68  {
69  (void)block;
70  }
71 };
72 
77 {
83 
88  static constexpr lu_factor_t loop_unrolling = lu_factor_t::lu16;
89 };
90 
91 } // namespace mtv
92 
93 namespace detail { namespace mtv {
94 
95 #ifdef MDDS_MULTI_TYPE_VECTOR_DEBUG
96 
97 template<typename T, typename = void>
98 struct has_trace : std::false_type
99 {
100 };
101 
102 template<typename T>
103 struct has_trace<T, decltype((void)T::trace)> : std::true_type
104 {
105 };
106 
107 template<typename Trait>
108 struct call_trace
109 {
110  int& call_depth;
111 
112  call_trace(int& _call_depth) : call_depth(_call_depth)
113  {
114  ++call_depth;
115  }
116  ~call_trace() noexcept
117  {
118  --call_depth;
119  }
120 
121  void call(std::false_type, const ::mdds::mtv::trace_method_properties_t&) const
122  {
123  // sink
124  }
125 
126  void call(std::true_type, const ::mdds::mtv::trace_method_properties_t& props) const
127  {
128  // In case of recursive calls, only trace the first encountered method.
129  if (call_depth <= 1)
130  Trait::trace(props);
131  }
132 
133  void operator()(const ::mdds::mtv::trace_method_properties_t& props) const
134  {
135  call(has_trace<Trait>{}, props);
136  }
137 };
138 
139 #endif
140 
141 inline void throw_block_position_not_found(
142  const char* method_sig, int line, size_t pos, size_t block_size, size_t container_size)
143 {
144  std::ostringstream os;
145  os << method_sig << "#" << line << ": block position not found! (logical pos=" << pos
146  << ", block size=" << block_size << ", logical size=" << container_size << ")";
147  throw std::out_of_range(os.str());
148 }
149 
168 template<typename _T, typename _SizeT>
169 std::pair<_SizeT, bool> calc_input_end_position(const _T& it_begin, const _T& it_end, _SizeT pos, _SizeT total_size)
170 {
171  using ret_type = std::pair<_SizeT, bool>;
172 
173  _SizeT length = std::distance(it_begin, it_end);
174  if (!length)
175  // empty data array. nothing to do.
176  return ret_type(0, false);
177 
178  _SizeT end_pos = pos + length - 1;
179  if (end_pos >= total_size)
180  throw std::out_of_range("Input data sequence is too long.");
181 
182  return ret_type(end_pos, true);
183 }
184 
185 template<typename T>
186 T advance_position(const T& pos, int steps)
187 {
188  T ret = pos;
189 
190  if (steps > 0)
191  {
192  while (steps > 0)
193  {
194  if (ret.second + steps < ret.first->size)
195  {
196  // element is still in the same block.
197  ret.second += steps;
198  break;
199  }
200  else
201  {
202  steps -= static_cast<int>(ret.first->size - ret.second);
203  ++ret.first;
204  ret.second = 0;
205  }
206  }
207  }
208  else
209  {
210  while (steps < 0)
211  {
212  if (static_cast<int>(ret.second) >= -steps)
213  {
214  ret.second += steps;
215  break;
216  }
217  else
218  {
219  steps += static_cast<int>(ret.second + 1);
220  --ret.first;
221  ret.second = ret.first->size - 1;
222  }
223  }
224  }
225 
226  return ret;
227 }
228 
229 template<typename _Blk>
230 inline typename _Blk::value_type get_block_element_at(const mdds::mtv::base_element_block& data, size_t offset)
231 {
232  return _Blk::at(data, offset);
233 }
234 
235 #ifndef MDDS_MULTI_TYPE_VECTOR_USE_DEQUE
236 
237 template<>
238 inline bool get_block_element_at<mdds::mtv::boolean_element_block>(
239  const mdds::mtv::base_element_block& data, size_t offset)
240 {
241  auto it = mdds::mtv::boolean_element_block::cbegin(data);
242  std::advance(it, offset);
243  return *it;
244 }
245 
246 #endif
247 
248 }} // namespace detail::mtv
249 
250 } // namespace mdds
251 
252 #ifdef MDDS_MULTI_TYPE_VECTOR_DEBUG
253 
254 #define MDDS_MTV_TRACE(method_type) \
255  ::mdds::detail::mtv::call_trace<Trait> mdds_mtv_ct(m_trace_call_depth); \
256  mdds_mtv_ct({trace_method_t::method_type, this, __func__, "", __FILE__, __LINE__})
257 
258 #define MDDS_MTV_TRACE_ARGS(method_type, stream) \
259  ::mdds::detail::mtv::call_trace<Trait> mdds_mtv_ct(m_trace_call_depth); \
260  do \
261  { \
262  std::ostringstream _os_; \
263  _os_ << stream; \
264  mdds_mtv_ct({trace_method_t::method_type, this, __func__, _os_.str(), __FILE__, __LINE__}); \
265  } while (false)
266 
267 #else
268 
269 #define MDDS_MTV_TRACE(...)
270 
271 #define MDDS_MTV_TRACE_ARGS(...)
272 
273 #endif
274 
275 #endif
276 
277 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static constexpr lu_factor_t loop_unrolling
Definition: util.hpp:88
Definition: util.hpp:76
Definition: util.hpp:44
void element_block_acquired(const base_element_block *block)
Definition: util.hpp:54
void element_block_released(const base_element_block *block)
Definition: util.hpp:67
Definition: flat_segment_tree.hpp:46
Definition: types.hpp:173