File indexing completed on 2025-01-18 09:27:59
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include <iterator>
0012 #include <type_traits>
0013 #include <utility>
0014
0015 namespace Acts::detail {
0016
0017 template <typename Callable, typename iterator_t, bool force_const>
0018 struct TransformRangeIterator;
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033 template <typename Callable, typename container_t>
0034 struct TransformRange {
0035 private:
0036 using internal_value_type = typename container_t::value_type;
0037
0038 static_assert(std::is_reference_v<decltype(Callable::apply(
0039 std::declval<internal_value_type>()))>,
0040 "The callable must return a reference type");
0041
0042 using raw_value_type = std::remove_reference_t<decltype(Callable::apply(
0043 std::declval<internal_value_type>()))>;
0044
0045 public:
0046
0047
0048
0049 using value_type =
0050 std::conditional_t<std::is_const_v<container_t>,
0051 std::add_const_t<raw_value_type>, raw_value_type>;
0052
0053 using reference = value_type&;
0054 using const_reference = const value_type&;
0055
0056 using iterator = TransformRangeIterator<
0057 Callable,
0058 std::conditional_t<std::is_const_v<container_t>,
0059 typename container_t::const_iterator,
0060 typename container_t::iterator>,
0061 std::is_const_v<container_t>>;
0062 using const_iterator =
0063 TransformRangeIterator<Callable, typename container_t::const_iterator,
0064 true>;
0065
0066
0067
0068
0069 TransformRange(Callable&& , container_t& container)
0070 : m_container(&container) {}
0071
0072
0073
0074 explicit TransformRange(container_t& container) : m_container(&container) {}
0075
0076
0077
0078
0079
0080 reference operator[](std::size_t i) {
0081 return Callable::apply((*m_container)[i]);
0082 }
0083
0084
0085
0086
0087
0088 const_reference operator[](std::size_t i) const {
0089 return std::as_const(Callable::apply((*m_container)[i]));
0090 }
0091
0092
0093
0094
0095
0096 reference at(std::size_t i) { return Callable::apply(m_container->at(i)); }
0097
0098
0099
0100
0101
0102 const_reference at(std::size_t i) const {
0103 return std::as_const(Callable::apply(m_container->at(i)));
0104 }
0105
0106
0107
0108 iterator begin() { return iterator{m_container->begin()}; }
0109
0110
0111
0112 iterator end() { return iterator{m_container->end()}; }
0113
0114
0115
0116 const_iterator begin() const { return const_iterator{m_container->begin()}; }
0117
0118
0119
0120 const_iterator cbegin() const { return begin(); }
0121
0122
0123
0124 const_iterator end() const { return const_iterator{m_container->end()}; }
0125
0126
0127
0128 const_iterator cend() const { return end(); }
0129
0130
0131
0132 std::size_t size() const { return m_container->size(); }
0133
0134
0135
0136 bool empty() const { return m_container->empty(); }
0137
0138 private:
0139 container_t* m_container;
0140 };
0141
0142
0143
0144
0145
0146
0147
0148 template <typename Callable, typename iterator_t, bool force_const>
0149 struct TransformRangeIterator {
0150 private:
0151 using internal_value_type =
0152 typename std::iterator_traits<iterator_t>::value_type;
0153
0154 using raw_value_type = std::remove_reference_t<decltype(Callable::apply(
0155 std::declval<internal_value_type>()))>;
0156
0157 public:
0158
0159
0160
0161 using value_type =
0162 std::conditional_t<force_const, std::add_const_t<raw_value_type>,
0163 raw_value_type>;
0164
0165 using difference_type =
0166 typename std::iterator_traits<iterator_t>::difference_type;
0167 using pointer = std::remove_reference_t<value_type>*;
0168 using reference = value_type&;
0169 using iterator_category = std::forward_iterator_tag;
0170
0171
0172 explicit TransformRangeIterator(iterator_t iterator) : m_iterator(iterator) {}
0173
0174
0175
0176 reference operator*() { return Callable::apply(*m_iterator); }
0177
0178
0179
0180 reference operator*() const { return Callable::apply(*m_iterator); }
0181
0182
0183
0184 TransformRangeIterator& operator++() {
0185 ++m_iterator;
0186 return *this;
0187 }
0188
0189
0190
0191 bool operator==(const TransformRangeIterator& other) const {
0192 return m_iterator == other.m_iterator;
0193 }
0194
0195
0196
0197 bool operator!=(const TransformRangeIterator& other) const {
0198 return m_iterator != other.m_iterator;
0199 }
0200
0201 private:
0202 iterator_t m_iterator;
0203 };
0204
0205
0206 struct Dereference {
0207 template <typename input_t>
0208 constexpr static decltype(auto) apply(input_t&& value) {
0209 return *value;
0210 }
0211 };
0212
0213
0214 struct ConstDereference {
0215 template <typename input_t>
0216 constexpr static decltype(auto) apply(input_t&& value) {
0217 return std::as_const(*value);
0218 }
0219 };
0220
0221
0222 struct DotGet {
0223 template <typename input_t>
0224 constexpr static decltype(auto) apply(input_t&& value) {
0225 return value.get();
0226 }
0227 };
0228
0229 }