16#ifndef RANS_INTERNAL_TRANSFORM_ALGORITHM_H_
17#define RANS_INTERNAL_TRANSFORM_ALGORITHM_H_
31template <
class container_T>
32class SparseVectorIterator;
34template <class IT, std::enable_if_t<isPair_v<typename std::iterator_traits<IT>::value_type>,
bool> =
true>
35inline auto getValue(IT iter) ->
typename std::iterator_traits<IT>::value_type::second_type
40template <
typename source_T,
typename value_T>
41inline auto getValue(
const std::pair<source_T, value_T>& pair) -> value_T
46template <
class IT, std::enable_if_t<std::is_po
inter_v<std::remove_reference_t<IT>>,
bool> = true>
47inline auto getValue(IT iter) ->
typename std::iterator_traits<IT>::value_type
52template <class IT, std::enable_if_t<isPair_v<typename std::iterator_traits<IT>::value_type>,
bool> =
true>
53inline void setValue(IT iter,
const typename std::iterator_traits<IT>::value_type::second_type&
value)
55 return iter->second =
value;
58template <
class IT, std::enable_if_t<std::is_po
inter_v<std::remove_reference_t<IT>>,
bool> = true>
59inline void setValue(IT iter, std::add_lvalue_reference_t<std::add_const_t<
typename std::iterator_traits<IT>::value_type>>
value)
64template <
typename container_T, std::enable_if_t<isDenseContainer_v<container_T>,
bool> = true>
65inline constexpr auto getIndex(
const container_T& container,
typename container_T::const_iterator iter) ->
typename container_T::source_type
67 return container.getOffset() + std::distance(container.begin(), iter);
70template <
typename container_T, std::enable_if_t<isAdaptiveContainer_v<container_T> ||
71 isHashContainer_v<container_T> ||
72 isSetContainer_v<container_T>,
74inline constexpr auto getIndex(
const container_T& container,
typename container_T::const_iterator iter) ->
typename container_T::source_type
79template <
typename container_T,
class F>
80inline void forEachIndexValue(
const container_T& container,
typename container_T::const_iterator begin,
typename container_T::const_iterator
end, F functor)
85template <
typename container_T,
class F, std::enable_if_t<isStorageContainer_v<container_T>,
bool> = true>
86inline void forEachIndexValue(container_T& container,
typename container_T::iterator begin,
typename container_T::iterator
end, F functor)
91template <
typename container_T,
class F>
97template <
typename container_T,
class F>
103template <
typename container_T>
104inline auto trim(
typename container_T::iterator begin,
typename container_T::iterator
end,
typename container_T::const_reference zeroElem = {})
105 -> std::pair<typename container_T::iterator, typename container_T::iterator>
107 return algorithmImpl::trim<container_T, typename container_T::iterator>(begin,
end, zeroElem);
110template <
typename container_T>
111inline auto trim(
typename container_T::const_iterator begin,
typename container_T::const_iterator
end,
typename container_T::const_reference zeroElem = {})
112 -> std::pair<typename container_T::const_iterator, typename container_T::const_iterator>
114 return algorithmImpl::trim<container_T, typename container_T::const_iterator>(begin,
end, zeroElem);
117template <
typename container_T, std::enable_if_t<isStorageContainer_v<container_T>,
bool> = true>
118inline decltype(
auto)
trim(container_T& container,
const typename container_T::value_type& zeroElem = {})
120 return algorithmImpl::trim<container_T, typename container_T::iterator>(container.begin(), container.end(), zeroElem);
123template <
typename container_T, std::enable_if_t<isContainer_v<container_T>,
bool> = true>
124inline decltype(
auto)
trim(
const container_T& container,
const typename container_T::value_type& zeroElem = {})
126 return algorithmImpl::trim<container_T, typename container_T::const_iterator>(container.begin(), container.end(), zeroElem);
129template <
class container_T,
130 std::enable_if_t<isDenseContainer_v<container_T> ||
131 isAdaptiveContainer_v<container_T> ||
132 isSetContainer_v<container_T>,
135 typename container_T::const_iterator begin,
136 typename container_T::const_iterator
end,
137 typename container_T::const_reference zeroElem = {})
138 -> std::pair<typename container_T::source_type, typename container_T::source_type>
140 auto [trimmedBegin, trimmedEnd] = trim<container_T>(begin,
end, zeroElem);
142 if (trimmedBegin != trimmedEnd) {
143 const auto min =
getIndex(container, trimmedBegin);
144 const auto max =
getIndex(container, --trimmedEnd);
148 return {container.getOffset(), container.getOffset()};
151template <
typename container_T, std::enable_if_t<isHashContainer_v<container_T>,
bool> = true>
152auto getMinMax(
const container_T& container,
153 typename container_T::const_iterator begin,
154 typename container_T::const_iterator
end,
155 typename container_T::const_reference zeroElem = {})
156 -> std::pair<typename container_T::source_type, typename container_T::source_type>
158 using iterator_type =
typename container_T::const_iterator;
159 using value_type =
typename std::iterator_traits<iterator_type>::value_type::second_type;
160 using return_type = std::pair<value_type, value_type>;
162 bool empty = container.empty();
164 if constexpr (isRenormedHistogram_v<container_T>) {
165 empty = container.getNumSamples() == container.getIncompressibleSymbolFrequency();
169 return return_type{container.getOffset(), container.getOffset()};
172 const auto [minIter, maxIter] = std::minmax_element(begin,
end, [](
const auto&
a,
const auto&
b) {
return a.first <
b.first; });
173 return return_type{minIter->first, maxIter->first};
176template <
typename container_T>
177auto getMinMax(
const container_T& container,
typename container_T::const_reference zeroElem = {})
178 -> std::pair<typename container_T::source_type, typename container_T::source_type>
180 return getMinMax(container, container.begin(), container.end(), zeroElem);
common helper classes and functions
GLboolean GLboolean GLboolean b
GLsizei const GLfloat * value
GLboolean GLboolean GLboolean GLboolean a
void forEachIndexValue(container_T &&container, IT begin, IT end, F functor)
auto trim(typename container_T::iterator begin, typename container_T::iterator end, typename container_T::const_reference zeroElem={}) -> std::pair< typename container_T::iterator, typename container_T::iterator >
auto getMinMax(const container_T &container, typename container_T::const_iterator begin, typename container_T::const_iterator end, typename container_T::const_reference zeroElem={}) -> std::pair< typename container_T::source_type, typename container_T::source_type >
void setValue(IT iter, const typename std::iterator_traits< IT >::value_type::second_type &value)
auto getValue(IT iter) -> typename std::iterator_traits< IT >::value_type::second_type
void forEachIndexValue(const container_T &container, typename container_T::const_iterator begin, typename container_T::const_iterator end, F functor)
constexpr auto getIndex(const container_T &container, typename container_T::const_iterator iter) -> typename container_T::source_type