File indexing completed on 2025-10-15 08:05:57
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include <boost/test/tools/old/interface.hpp>
0010 #include <boost/test/unit_test.hpp>
0011 #include <boost/test/unit_test_suite.hpp>
0012
0013 #include "Acts/Utilities/TransformRange.hpp"
0014
0015 #include <algorithm>
0016 #include <ranges>
0017
0018 using namespace Acts;
0019
0020 namespace ActsTests {
0021
0022 BOOST_AUTO_TEST_SUITE(UtilitiesSuite)
0023
0024 auto checkSameAddresses = [](const auto& orig, auto& act) {
0025 BOOST_CHECK_EQUAL(orig.size(), act.size());
0026 auto it = act.begin();
0027 for (std::size_t i = 0; i < orig.size(); ++i) {
0028 BOOST_CHECK_EQUAL(orig.at(i).get(), &act.at(i));
0029 BOOST_CHECK_EQUAL(orig.at(i).get(), &act[i]);
0030 BOOST_CHECK_EQUAL(*orig.at(i), act.at(i));
0031
0032 BOOST_CHECK_EQUAL(orig.at(i).get(), &*it);
0033 BOOST_CHECK_EQUAL(*orig.at(i).get(), *it);
0034
0035 ++it;
0036 }
0037
0038 BOOST_CHECK(it == act.end());
0039 };
0040
0041 BOOST_AUTO_TEST_CASE(TransformRangeDeref) {
0042 {
0043 std::vector<std::unique_ptr<int>> v;
0044 v.push_back(std::make_unique<int>(1));
0045 v.push_back(std::make_unique<int>(2));
0046 v.push_back(std::make_unique<int>(3));
0047
0048 {
0049 auto r = detail::TransformRange{detail::Dereference{}, v};
0050 static_assert(std::is_same_v<decltype(r)::value_type, int>);
0051 static_assert(std::is_same_v<decltype(r)::reference, int&>);
0052 static_assert(std::is_same_v<decltype(r)::const_reference, const int&>);
0053 static_assert(std::is_same_v<decltype(r.at(0)), int&>);
0054 static_assert(std::is_same_v<decltype(r[0]), int&>);
0055 static_assert(std::is_same_v<decltype(*r.begin()), int&>);
0056 static_assert(std::is_same_v<decltype(*r.cbegin()), const int&>);
0057
0058 r.at(2) = 4;
0059 BOOST_CHECK_EQUAL(*v.at(2), 4);
0060
0061 checkSameAddresses(v, r);
0062
0063 const auto& r_cref = r;
0064 static_assert(std::is_same_v<decltype(r_cref.at(0)), const int&>);
0065 static_assert(std::is_same_v<decltype(r_cref[0]), const int&>);
0066 static_assert(std::is_same_v<decltype(*r_cref.begin()), const int&>);
0067 static_assert(std::is_same_v<decltype(*(++r_cref.begin())), const int&>);
0068 checkSameAddresses(v, r_cref);
0069
0070 auto cr = detail::TransformRange{detail::ConstDereference{}, v};
0071 static_assert(std::is_same_v<decltype(cr)::value_type, const int>);
0072 static_assert(std::is_same_v<decltype(cr)::reference, const int&>);
0073 static_assert(std::is_same_v<decltype(cr)::const_reference, const int&>);
0074 static_assert(std::is_same_v<decltype(cr.at(0)), const int&>);
0075 static_assert(std::is_same_v<decltype(cr[0]), const int&>);
0076 static_assert(std::is_same_v<decltype(*cr.begin()), const int&>);
0077 static_assert(std::is_same_v<decltype(*(++cr.begin())), const int&>);
0078 checkSameAddresses(v, cr);
0079
0080 const auto& cr_cref = cr;
0081 static_assert(std::is_same_v<decltype(cr_cref.at(0)), const int&>);
0082 static_assert(std::is_same_v<decltype(cr_cref[0]), const int&>);
0083 static_assert(std::is_same_v<decltype(*cr_cref.begin()), const int&>);
0084 static_assert(std::is_same_v<decltype(*(++cr_cref.begin())), const int&>);
0085 checkSameAddresses(v, cr_cref);
0086
0087 std::vector<int> act;
0088 std::copy(cr_cref.begin(), cr_cref.end(), std::back_inserter(act));
0089 std::vector<int> exp = {1, 2, 4};
0090 BOOST_CHECK_EQUAL_COLLECTIONS(exp.begin(), exp.end(), act.begin(),
0091 act.end());
0092 }
0093
0094 std::vector<int*> raw_v;
0095 for (auto& ptr : v) {
0096 raw_v.push_back(ptr.get());
0097 }
0098 {
0099 auto r = detail::TransformRange{detail::Dereference{}, raw_v};
0100 static_assert(std::is_same_v<decltype(r)::value_type, int>);
0101 static_assert(std::is_same_v<decltype(r)::reference, int&>);
0102 static_assert(std::is_same_v<decltype(r)::const_reference, const int&>);
0103 static_assert(std::is_same_v<decltype(r.at(0)), int&>);
0104 static_assert(std::is_same_v<decltype(r[0]), int&>);
0105 static_assert(std::is_same_v<decltype(*r.begin()), int&>);
0106 static_assert(std::is_same_v<decltype(*(++r.begin())), int&>);
0107 checkSameAddresses(v, r);
0108
0109 std::vector<int> unpacked;
0110 std::ranges::transform(r, std::back_inserter(unpacked),
0111 [](auto val) { return val; });
0112 std::vector<int> exp = {1, 2, 4};
0113
0114 BOOST_CHECK_EQUAL_COLLECTIONS(exp.begin(), exp.end(), unpacked.begin(),
0115 unpacked.end());
0116
0117 auto cr = detail::TransformRange{detail::ConstDereference{}, raw_v};
0118 static_assert(std::is_same_v<decltype(cr)::value_type, const int>);
0119 static_assert(std::is_same_v<decltype(cr)::reference, const int&>);
0120 static_assert(std::is_same_v<decltype(cr)::const_reference, const int&>);
0121 static_assert(std::is_same_v<decltype(cr.at(0)), const int&>);
0122 static_assert(std::is_same_v<decltype(cr[0]), const int&>);
0123 static_assert(std::is_same_v<decltype(*cr.begin()), const int&>);
0124 static_assert(std::is_same_v<decltype(*(++cr.begin())), const int&>);
0125 checkSameAddresses(v, r);
0126
0127 unpacked.clear();
0128 std::ranges::transform(cr, std::back_inserter(unpacked),
0129 [](auto val) { return val; });
0130
0131 BOOST_CHECK_EQUAL_COLLECTIONS(exp.begin(), exp.end(), unpacked.begin(),
0132 unpacked.end());
0133 }
0134 }
0135
0136 {
0137 std::vector<std::unique_ptr<const int>> v;
0138 v.push_back(std::make_unique<const int>(1));
0139 v.push_back(std::make_unique<const int>(2));
0140 v.push_back(std::make_unique<const int>(3));
0141
0142 {
0143 auto r = detail::TransformRange{detail::Dereference{}, v};
0144 static_assert(std::is_same_v<decltype(r)::value_type, const int>);
0145 static_assert(std::is_same_v<decltype(r)::reference, const int&>);
0146 static_assert(std::is_same_v<decltype(r)::const_reference, const int&>);
0147 static_assert(std::is_same_v<decltype(r.at(0)), const int&>);
0148 static_assert(std::is_same_v<decltype(r[0]), const int&>);
0149 static_assert(std::is_same_v<decltype(*r.begin()), const int&>);
0150 static_assert(std::is_same_v<decltype(*(++r.begin())), const int&>);
0151 checkSameAddresses(v, r);
0152
0153 std::vector<int> unpacked;
0154 std::ranges::transform(r, std::back_inserter(unpacked),
0155 [](auto val) { return val; });
0156
0157 BOOST_CHECK(unpacked == std::vector<int>({1, 2, 3}));
0158 }
0159
0160 std::vector<const int*> raw_v;
0161 for (auto& ptr : v) {
0162 raw_v.push_back(ptr.get());
0163 }
0164 {
0165 auto r = detail::TransformRange{detail::Dereference{}, raw_v};
0166 static_assert(std::is_same_v<decltype(r)::value_type, const int>);
0167 static_assert(std::is_same_v<decltype(r)::reference, const int&>);
0168 static_assert(std::is_same_v<decltype(r)::const_reference, const int&>);
0169 static_assert(std::is_same_v<decltype(r.at(0)), const int&>);
0170 static_assert(std::is_same_v<decltype(r[0]), const int&>);
0171 static_assert(std::is_same_v<decltype(*r.begin()), const int&>);
0172 static_assert(std::is_same_v<decltype(*(++r.begin())), const int&>);
0173 checkSameAddresses(v, r);
0174 }
0175 }
0176 }
0177
0178 BOOST_AUTO_TEST_CASE(TransformRangeFromConstRef) {
0179 std::vector<std::unique_ptr<int>> v;
0180 v.push_back(std::make_unique<int>(1));
0181 v.push_back(std::make_unique<int>(2));
0182 v.push_back(std::make_unique<int>(3));
0183
0184 const auto& cv = v;
0185
0186 {
0187 auto r_cv = detail::TransformRange{detail::Dereference{}, cv};
0188 static_assert(std::is_same_v<decltype(r_cv)::value_type, const int>);
0189 static_assert(std::is_same_v<decltype(r_cv)::reference, const int&>);
0190 static_assert(std::is_same_v<decltype(r_cv)::const_reference, const int&>);
0191 static_assert(std::is_same_v<decltype(r_cv.at(0)), const int&>);
0192 static_assert(std::is_same_v<decltype(r_cv[0]), const int&>);
0193 static_assert(std::is_same_v<decltype(*r_cv.begin()), const int&>);
0194 static_assert(std::is_same_v<decltype(*(++r_cv.begin())), const int&>);
0195
0196 checkSameAddresses(v, r_cv);
0197 checkSameAddresses(cv, r_cv);
0198
0199 std::vector<int> act;
0200 std::copy(r_cv.begin(), r_cv.end(), std::back_inserter(act));
0201 std::vector<int> exp = {1, 2, 3};
0202 BOOST_CHECK_EQUAL_COLLECTIONS(exp.begin(), exp.end(), act.begin(),
0203 act.end());
0204 }
0205
0206 {
0207 auto r_cv = detail::TransformRange{detail::ConstDereference{}, cv};
0208 static_assert(std::is_same_v<decltype(r_cv)::value_type, const int>);
0209 static_assert(std::is_same_v<decltype(r_cv)::reference, const int&>);
0210 static_assert(std::is_same_v<decltype(r_cv)::const_reference, const int&>);
0211 static_assert(std::is_same_v<decltype(r_cv.at(0)), const int&>);
0212 static_assert(std::is_same_v<decltype(r_cv[0]), const int&>);
0213 static_assert(std::is_same_v<decltype(*r_cv.begin()), const int&>);
0214 static_assert(std::is_same_v<decltype(*(++r_cv.begin())), const int&>);
0215
0216 checkSameAddresses(v, r_cv);
0217 checkSameAddresses(cv, r_cv);
0218
0219 std::vector<int> act;
0220 std::copy(r_cv.begin(), r_cv.end(), std::back_inserter(act));
0221 std::vector<int> exp = {1, 2, 3};
0222 BOOST_CHECK_EQUAL_COLLECTIONS(exp.begin(), exp.end(), act.begin(),
0223 act.end());
0224 }
0225 }
0226
0227 BOOST_AUTO_TEST_CASE(TransformRangeReferenceWrappers) {
0228 int a = 5;
0229 int b = 6;
0230 int c = 7;
0231
0232 std::vector<std::reference_wrapper<int>> v = {a, b, c};
0233 BOOST_CHECK_EQUAL(&v[0].get(), &a);
0234
0235 auto r = detail::TransformRange{detail::DotGet{}, v};
0236 static_assert(std::is_same_v<decltype(r)::value_type, int>);
0237 static_assert(std::is_same_v<decltype(r)::reference, int&>);
0238 static_assert(std::is_same_v<decltype(r)::const_reference, const int&>);
0239 static_assert(std::is_same_v<decltype(r.at(0)), int&>);
0240 static_assert(std::is_same_v<decltype(r[0]), int&>);
0241 static_assert(std::is_same_v<decltype(*r.begin()), int&>);
0242 static_assert(std::is_same_v<decltype(*(++r.begin())), int&>);
0243
0244 BOOST_CHECK_EQUAL(r.at(0), 5);
0245 BOOST_CHECK_EQUAL(&r.at(0), &a);
0246 BOOST_CHECK_EQUAL(r[0], 5);
0247 BOOST_CHECK_EQUAL(&r[0], &a);
0248 BOOST_CHECK_EQUAL(*r.begin(), 5);
0249 BOOST_CHECK_EQUAL(&*r.begin(), &a);
0250
0251 std::vector<int> act;
0252 std::copy(r.begin(), r.end(), std::back_inserter(act));
0253 std::vector<int> exp = {5, 6, 7};
0254 BOOST_CHECK_EQUAL_COLLECTIONS(exp.begin(), exp.end(), act.begin(), act.end());
0255 }
0256
0257 BOOST_AUTO_TEST_CASE(Ranges) {
0258 std::vector<std::unique_ptr<int>> v;
0259 v.push_back(std::make_unique<int>(1));
0260 v.push_back(std::make_unique<int>(2));
0261 v.push_back(std::make_unique<int>(3));
0262 v.push_back(std::make_unique<int>(4));
0263 v.push_back(std::make_unique<int>(5));
0264 auto r = detail::TransformRange{detail::Dereference{}, v};
0265
0266 std::vector<int> results;
0267 std::ranges::copy(r | std::views::transform([](int val) { return val * 3; }) |
0268 std::views::filter([](int val) { return val < 10; }),
0269 std::back_inserter(results));
0270 BOOST_CHECK_EQUAL(results.size(), 3);
0271 std::vector exp{3, 6, 9};
0272 BOOST_CHECK_EQUAL_COLLECTIONS(exp.begin(), exp.end(), results.begin(),
0273 results.end());
0274 }
0275
0276 BOOST_AUTO_TEST_SUITE_END()
0277
0278 }