mdds
util.hpp
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 
3 // SPDX-FileCopyrightText: 2021 - 2025 Kohei Yoshida
4 //
5 // SPDX-License-Identifier: MIT
6 
7 #pragma once
8 
9 #include "./block_funcs.hpp"
10 
11 #include <sstream>
12 
13 namespace mdds { namespace mtv {
14 
20 {
30  {
31  (void)block;
32  }
33 
43  {
44  (void)block;
45  }
46 };
47 
49 {
50 };
51 
56 {
62 
67  static constexpr lu_factor_t loop_unrolling = lu_factor_t::lu16;
68 
73 
83 };
84 
85 namespace detail {
86 
89 {
90 };
91 
92 #ifdef MDDS_MULTI_TYPE_VECTOR_TRACE
93 
94 template<typename T, typename = void>
95 struct has_trace : std::false_type
96 {
97 };
98 
99 template<typename T>
100 struct has_trace<T, decltype((void)T::trace)> : std::true_type
101 {
102 };
103 
104 template<typename Traits>
105 struct call_trace
106 {
107  int& call_depth;
108 
109  call_trace(int& _call_depth) : call_depth(_call_depth)
110  {
111  ++call_depth;
112  }
113  ~call_trace() noexcept
114  {
115  --call_depth;
116  }
117 
118  void call(std::false_type, const ::mdds::mtv::trace_method_properties_t&) const
119  {
120  // sink
121  }
122 
123  void call(std::true_type, const ::mdds::mtv::trace_method_properties_t& props) const
124  {
125  // In case of recursive calls, only trace the first encountered method.
126  if (call_depth <= 1)
127  Traits::trace(props);
128  }
129 
130  void operator()(const ::mdds::mtv::trace_method_properties_t& props) const
131  {
132  call(has_trace<Traits>{}, props);
133  }
134 };
135 
136 #endif
137 
138 inline void throw_block_position_not_found(
139  const char* method_sig, int line, size_t pos, size_t block_size, size_t container_size)
140 {
141  std::ostringstream os;
142  os << method_sig << "#" << line << ": block position not found! (logical pos=" << pos
143  << ", block size=" << block_size << ", logical size=" << container_size << ")";
144  throw std::out_of_range(os.str());
145 }
146 
165 template<typename _T, typename _SizeT>
166 std::pair<_SizeT, bool> calc_input_end_position(const _T& it_begin, const _T& it_end, _SizeT pos, _SizeT total_size)
167 {
168  using ret_type = std::pair<_SizeT, bool>;
169 
170  _SizeT length = std::distance(it_begin, it_end);
171  if (!length)
172  // empty data array. nothing to do.
173  return ret_type(0, false);
174 
175  _SizeT end_pos = pos + length - 1;
176  if (end_pos >= total_size)
177  throw std::out_of_range("Input data sequence is too long.");
178 
179  return ret_type(end_pos, true);
180 }
181 
182 template<typename T>
183 T advance_position(const T& pos, int steps)
184 {
185  T ret = pos;
186 
187  if (steps > 0)
188  {
189  while (steps > 0)
190  {
191  if (ret.second + steps < ret.first->size)
192  {
193  // element is still in the same block.
194  ret.second += steps;
195  break;
196  }
197  else
198  {
199  steps -= static_cast<int>(ret.first->size - ret.second);
200  ++ret.first;
201  ret.second = 0;
202  }
203  }
204  }
205  else
206  {
207  while (steps < 0)
208  {
209  if (static_cast<int>(ret.second) >= -steps)
210  {
211  ret.second += steps;
212  break;
213  }
214  else
215  {
216  steps += static_cast<int>(ret.second + 1);
217  --ret.first;
218  ret.second = ret.first->size - 1;
219  }
220  }
221  }
222 
223  return ret;
224 }
225 
226 } // namespace detail
227 
228 }} // namespace mdds::mtv
229 
230 #ifdef MDDS_MULTI_TYPE_VECTOR_TRACE
231 
232 #define MDDS_MTV_TRACE(method_type) \
233  ::mdds::mtv::detail::call_trace<Traits> mdds_mtv_ct(m_trace_call_depth); \
234  mdds_mtv_ct({trace_method_t::method_type, this, __func__, "", __FILE__, __LINE__})
235 
236 #define MDDS_MTV_TRACE_ARGS(method_type, stream) \
237  ::mdds::mtv::detail::call_trace<Traits> mdds_mtv_ct(m_trace_call_depth); \
238  do \
239  { \
240  std::ostringstream _os_; \
241  _os_ << stream; \
242  mdds_mtv_ct({trace_method_t::method_type, this, __func__, _os_.str(), __FILE__, __LINE__}); \
243  } while (false)
244 
245 #else
246 
247 #define MDDS_MTV_TRACE(...)
248 
249 #define MDDS_MTV_TRACE_ARGS(...)
250 
251 #endif
252 
253 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Definition: util.hpp:19
void element_block_acquired(const base_element_block *block)
Definition: util.hpp:29
void element_block_released(const base_element_block *block)
Definition: util.hpp:42
Definition: util.hpp:55
Definition: cref_wrapper.hpp:12
Definition: block_funcs.hpp:42
Definition: types.hpp:134
Definition: util.hpp:48
static constexpr lu_factor_t loop_unrolling
Definition: util.hpp:67