Loading...
Searching...
No Matches
util.hpp
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
// SPDX-FileCopyrightText: 2021 - 2025 Kohei Yoshida
//
// SPDX-License-Identifier: MIT
#pragma once
#include "./block_funcs.hpp"
#include <sstream>
namespace mdds { namespace mtv {
struct empty_event_func
{
void element_block_acquired(const base_element_block* block)
{
(void)block;
}
void element_block_released(const base_element_block* block)
{
(void)block;
}
};
struct default_exec_policy
{
};
struct default_traits
{
using event_func = empty_event_func;
static constexpr lu_factor_t loop_unrolling = lu_factor_t::lu16;
using exec_policy = default_exec_policy;
using block_funcs = element_block_funcs<>;
};
namespace detail {
struct clone_construction_type
{
};
#ifdef MDDS_MULTI_TYPE_VECTOR_TRACE
template<typename T, typename = void>
struct has_trace : std::false_type
{
};
template<typename T>
struct has_trace<T, decltype((void)T::trace)> : std::true_type
{
};
template<typename Traits>
struct call_trace
{
int& call_depth;
call_trace(int& _call_depth) : call_depth(_call_depth)
{
++call_depth;
}
~call_trace() noexcept
{
--call_depth;
}
void call(std::false_type, const ::mdds::mtv::trace_method_properties_t&) const
{
// sink
}
void call(std::true_type, const ::mdds::mtv::trace_method_properties_t& props) const
{
// In case of recursive calls, only trace the first encountered method.
if (call_depth <= 1)
Traits::trace(props);
}
void operator()(const ::mdds::mtv::trace_method_properties_t& props) const
{
call(has_trace<Traits>{}, props);
}
};
#endif
inline void throw_block_position_not_found(
const char* method_sig, int line, size_t pos, size_t block_size, size_t container_size)
{
std::ostringstream os;
os << method_sig << "#" << line << ": block position not found! (logical pos=" << pos
<< ", block size=" << block_size << ", logical size=" << container_size << ")";
throw std::out_of_range(os.str());
}
template<typename _T, typename _SizeT>
std::pair<_SizeT, bool> calc_input_end_position(const _T& it_begin, const _T& it_end, _SizeT pos, _SizeT total_size)
{
using ret_type = std::pair<_SizeT, bool>;
_SizeT length = std::distance(it_begin, it_end);
if (!length)
// empty data array. nothing to do.
return ret_type(0, false);
_SizeT end_pos = pos + length - 1;
if (end_pos >= total_size)
throw std::out_of_range("Input data sequence is too long.");
return ret_type(end_pos, true);
}
template<typename T>
T advance_position(const T& pos, int steps)
{
T ret = pos;
if (steps > 0)
{
while (steps > 0)
{
if (ret.second + steps < ret.first->size)
{
// element is still in the same block.
ret.second += steps;
break;
}
else
{
steps -= static_cast<int>(ret.first->size - ret.second);
++ret.first;
ret.second = 0;
}
}
}
else
{
while (steps < 0)
{
if (static_cast<int>(ret.second) >= -steps)
{
ret.second += steps;
break;
}
else
{
steps += static_cast<int>(ret.second + 1);
--ret.first;
ret.second = ret.first->size - 1;
}
}
}
return ret;
}
} // namespace detail
}} // namespace mdds::mtv
#ifdef MDDS_MULTI_TYPE_VECTOR_TRACE
#define MDDS_MTV_TRACE(method_type) \
::mdds::mtv::detail::call_trace<Traits> mdds_mtv_ct(m_trace_call_depth); \
mdds_mtv_ct({trace_method_t::method_type, this, __func__, "", __FILE__, __LINE__})
#define MDDS_MTV_TRACE_ARGS(method_type, stream) \
::mdds::mtv::detail::call_trace<Traits> mdds_mtv_ct(m_trace_call_depth); \
do \
{ \
std::ostringstream _os_; \
_os_ << stream; \
mdds_mtv_ct({trace_method_t::method_type, this, __func__, _os_.str(), __FILE__, __LINE__}); \
} while (false)
#else
#define MDDS_MTV_TRACE(...)
#define MDDS_MTV_TRACE_ARGS(...)
#endif
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
mdds::mtv::base_element_block
Definition types.hpp:135
mdds::mtv::default_exec_policy
Definition util.hpp:49
mdds::mtv::default_traits
Definition util.hpp:56
mdds::mtv::default_traits::exec_policy
default_exec_policy exec_policy
Definition util.hpp:72
mdds::mtv::default_traits::loop_unrolling
static constexpr lu_factor_t loop_unrolling
Definition util.hpp:67
mdds::mtv::default_traits::event_func
empty_event_func event_func
Definition util.hpp:61
mdds::mtv::default_traits::block_funcs
element_block_funcs<> block_funcs
Definition util.hpp:82
mdds::mtv::detail::clone_construction_type
Definition util.hpp:89
mdds::mtv::element_block_funcs<>
mdds::mtv::empty_event_func
Definition util.hpp:20
mdds::mtv::empty_event_func::element_block_acquired
void element_block_acquired(const base_element_block *block)
Definition util.hpp:29
mdds::mtv::empty_event_func::element_block_released
void element_block_released(const base_element_block *block)
Definition util.hpp:42