Remove dependency on Boost.Tuple

This commit is contained in:
Christian Mazakas
2023-09-20 09:32:25 -07:00
parent 91f63697a7
commit 9d8beff688
5 changed files with 166 additions and 88 deletions

View File

@ -31,7 +31,6 @@
#include <boost/mp11/algorithm.hpp> #include <boost/mp11/algorithm.hpp>
#include <boost/mp11/list.hpp> #include <boost/mp11/list.hpp>
#include <boost/throw_exception.hpp> #include <boost/throw_exception.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/type_traits/add_lvalue_reference.hpp> #include <boost/type_traits/add_lvalue_reference.hpp>
#include <boost/type_traits/aligned_storage.hpp> #include <boost/type_traits/aligned_storage.hpp>
#include <boost/type_traits/alignment_of.hpp> #include <boost/type_traits/alignment_of.hpp>
@ -55,6 +54,12 @@
#include <type_traits> #include <type_traits>
#include <utility> #include <utility>
namespace boost {
namespace tuples {
struct null_type;
}
} // namespace boost
// BOOST_UNORDERED_SUPPRESS_DEPRECATED // BOOST_UNORDERED_SUPPRESS_DEPRECATED
// //
// Define to stop deprecation attributes // Define to stop deprecation attributes
@ -543,13 +548,10 @@ namespace boost {
// For backwards compatibility, implement a special case for // For backwards compatibility, implement a special case for
// piecewise_construct with boost::tuple // piecewise_construct with boost::tuple
template <typename A0> struct detect_boost_tuple template <typename A0> struct detect_std_tuple
{ {
template <typename T0, typename T1, typename T2, typename T3, template <class... Args>
typename T4, typename T5, typename T6, typename T7, typename T8, static choice1::type test(choice1, std::tuple<Args...> const&);
typename T9>
static choice1::type test(choice1,
boost::tuple<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9> const&);
static choice2::type test(choice2, ...); static choice2::type test(choice2, ...);
@ -562,25 +564,27 @@ namespace boost {
// Special case for piecewise_construct // Special case for piecewise_construct
template <class... Args, std::size_t... Is, class... TupleArgs> template <template <class...> class Tuple, class... Args,
std::size_t... Is, class... TupleArgs>
std::tuple<typename std::add_lvalue_reference<Args>::type...> std::tuple<typename std::add_lvalue_reference<Args>::type...>
to_std_tuple_impl(boost::mp11::mp_list<Args...>, to_std_tuple_impl(boost::mp11::mp_list<Args...>,
boost::tuple<TupleArgs...>& tuple, boost::mp11::index_sequence<Is...>) Tuple<TupleArgs...>& tuple, boost::mp11::index_sequence<Is...>)
{ {
(void)tuple; (void)tuple;
using std::get;
return std::tuple<typename std::add_lvalue_reference<Args>::type...>( return std::tuple<typename std::add_lvalue_reference<Args>::type...>(
boost::get<Is>(tuple)...); get<Is>(tuple)...);
} }
template <class T> template <class T>
using add_lvalue_reference_t = using add_lvalue_reference_t =
typename std::add_lvalue_reference<T>::type; typename std::add_lvalue_reference<T>::type;
template <class... Args> template <template <class...> class Tuple, class... Args>
boost::mp11::mp_transform<add_lvalue_reference_t, boost::mp11::mp_transform<add_lvalue_reference_t,
boost::mp11::mp_remove<std::tuple<Args...>, boost::mp11::mp_remove<std::tuple<Args...>,
boost::tuples::null_type> > boost::tuples::null_type> >
to_std_tuple(boost::tuple<Args...>& tuple) to_std_tuple(Tuple<Args...>& tuple)
{ {
using list = boost::mp11::mp_remove<boost::mp11::mp_list<Args...>, using list = boost::mp11::mp_remove<boost::mp11::mp_list<Args...>,
boost::tuples::null_type>; boost::tuples::null_type>;
@ -593,8 +597,8 @@ namespace boost {
template <typename Alloc, typename A, typename B, typename A0, template <typename Alloc, typename A, typename B, typename A0,
typename A1, typename A2> typename A1, typename A2>
inline typename std::enable_if<use_piecewise<A0>::value && inline typename std::enable_if<use_piecewise<A0>::value &&
detect_boost_tuple<A1>::value && !detect_std_tuple<A1>::value &&
detect_boost_tuple<A2>::value, !detect_std_tuple<A2>::value,
void>::type void>::type
construct_from_args( construct_from_args(
Alloc& alloc, std::pair<A, B>* address, A0&&, A1&& a1, A2&& a2) Alloc& alloc, std::pair<A, B>* address, A0&&, A1&& a1, A2&& a2)
@ -2886,25 +2890,22 @@ namespace boost {
return no_key(); return no_key();
} }
#define BOOST_UNORDERED_KEY_FROM_TUPLE(namespace_) \ template <template <class...> class Tuple, typename T2>
template <typename T2> \ static no_key extract(
static no_key extract( \ std::piecewise_construct_t, Tuple<> const&, T2 const&)
std::piecewise_construct_t, namespace_ tuple<> const&, T2 const&) \ {
{ \ return no_key();
return no_key(); \ }
} \
\
template <typename T, typename T2> \
static typename is_key<key_type, T>::type extract( \
std::piecewise_construct_t, namespace_ tuple<T> const& k, T2 const&) \
{ \
return typename is_key<key_type, T>::type(namespace_ get<0>(k)); \
}
BOOST_UNORDERED_KEY_FROM_TUPLE(boost::) template <template <class...> class Tuple, typename T, typename T2,
BOOST_UNORDERED_KEY_FROM_TUPLE(std::) typename std::enable_if<
!std::is_same<T, boost::tuples::null_type>::value, int>::type = 0>
#undef BOOST_UNORDERED_KEY_FROM_TUPLE static typename is_key<key_type, T>::type extract(
std::piecewise_construct_t, Tuple<T> const& k, T2 const&)
{
using std::get;
return typename is_key<key_type, T>::type(get<0>(k));
}
}; };
template <class Container, class Predicate> template <class Container, class Predicate>

View File

@ -23,6 +23,7 @@
#include <boost/limits.hpp> #include <boost/limits.hpp>
#include <boost/predef.h> #include <boost/predef.h>
#include <boost/static_assert.hpp> #include <boost/static_assert.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/type_traits/cv_traits.hpp> #include <boost/type_traits/cv_traits.hpp>
#include <boost/type_traits/is_const.hpp> #include <boost/type_traits/is_const.hpp>
#include <boost/type_traits/is_convertible.hpp> #include <boost/type_traits/is_convertible.hpp>

View File

@ -6,9 +6,10 @@
#include "../helpers/unordered.hpp" #include "../helpers/unordered.hpp"
#include <boost/functional/hash/hash.hpp>
#include "../helpers/test.hpp"
#include "../helpers/count.hpp" #include "../helpers/count.hpp"
#include "../helpers/test.hpp"
#include <boost/functional/hash/hash.hpp>
#include <boost/tuple/tuple.hpp>
#include <string> #include <string>
// Test that various emplace methods work with different numbers of // Test that various emplace methods work with different numbers of
@ -386,6 +387,7 @@ namespace emplace_tests {
template <class X> static void emplace_map(X*) template <class X> static void emplace_map(X*)
{ {
#ifdef BOOST_UNORDERED_FOA_TESTS
test::check_instances check_; test::check_instances check_;
typedef X container; typedef X container;
@ -394,7 +396,6 @@ namespace emplace_tests {
container x(10); container x(10);
return_type r1, r2; return_type r1, r2;
#ifdef BOOST_UNORDERED_FOA_TESTS
// 5/8 args + duplicate // 5/8 args + duplicate
emplace_value k1(5, "", 'b', 4, 5); emplace_value k1(5, "", 'b', 4, 5);
BOOST_TEST_EQ(check_.constructions(), 1); BOOST_TEST_EQ(check_.constructions(), 1);
@ -450,63 +451,135 @@ namespace emplace_tests {
BOOST_TEST_EQ(check_.instances(), 8); BOOST_TEST_EQ(check_.instances(), 8);
BOOST_TEST_EQ(check_.constructions(), 20); BOOST_TEST_EQ(check_.constructions(), 20);
#else #else
// 5/8 args + duplicate {
emplace_value k1(5, "", 'b', 4, 5); test::check_instances check_;
emplace_value m1(8, "xxx", 'z', 4, 5, 6, 7, 8);
r1 = x.emplace(std::piecewise_construct,
boost::make_tuple(5, "", 'b', 4, 5),
boost::make_tuple(8, "xxx", 'z', 4, 5, 6, 7, 8));
BOOST_TEST_EQ(x.size(), 1u);
BOOST_TEST(r1.second);
BOOST_TEST(x.find(k1) == r1.first);
BOOST_TEST(x.find(k1)->second == m1);
BOOST_TEST_EQ(check_.instances(), 4);
BOOST_TEST_EQ(check_.constructions(), 4);
r2 = x.emplace(std::piecewise_construct, typedef X container;
boost::make_tuple(5, "", 'b', 4, 5), typedef typename container::iterator iterator;
boost::make_tuple(8, "xxx", 'z', 4, 5, 6, 7, 8)); typedef std::pair<iterator, bool> return_type;
BOOST_TEST_EQ(x.size(), 1u); container x(10);
BOOST_TEST(!r2.second); return_type r1, r2;
BOOST_TEST(r1.first == r2.first);
BOOST_TEST(x.find(k1)->second == m1);
BOOST_TEST_EQ(check_.instances(), 4);
// constructions could possibly be 5 if the implementation only
// constructed the key.
BOOST_TEST_EQ(check_.constructions(), 6);
// 9/3 args + duplicates with hints, different mapped value. // 5/8 args + duplicate
emplace_value k1(5, "", 'b', 4, 5);
emplace_value m1(8, "xxx", 'z', 4, 5, 6, 7, 8);
r1 =
x.emplace(std::piecewise_construct, std::make_tuple(5, "", 'b', 4, 5),
std::make_tuple(8, "xxx", 'z', 4, 5, 6, 7, 8));
BOOST_TEST_EQ(x.size(), 1u);
BOOST_TEST(r1.second);
BOOST_TEST(x.find(k1) == r1.first);
BOOST_TEST(x.find(k1)->second == m1);
BOOST_TEST_EQ(check_.instances(), 4);
BOOST_TEST_EQ(check_.constructions(), 4);
emplace_value k2(9, "", 'b', 4, 5, 6, 7, 8, 9); r2 =
emplace_value m2(3, "aaa", 'm'); x.emplace(std::piecewise_construct, std::make_tuple(5, "", 'b', 4, 5),
r1 = x.emplace(std::piecewise_construct, std::make_tuple(8, "xxx", 'z', 4, 5, 6, 7, 8));
boost::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9), BOOST_TEST_EQ(x.size(), 1u);
boost::make_tuple(3, "aaa", 'm')); BOOST_TEST(!r2.second);
BOOST_TEST_EQ(x.size(), 2u); BOOST_TEST(r1.first == r2.first);
BOOST_TEST(r1.second); BOOST_TEST(x.find(k1)->second == m1);
BOOST_TEST(r1.first->first.arg_count == 9); BOOST_TEST_EQ(check_.instances(), 4);
BOOST_TEST(r1.first->second.arg_count == 3); // constructions could possibly be 5 if the implementation only
BOOST_TEST(x.find(k2) == r1.first); // constructed the key.
BOOST_TEST(x.find(k2)->second == m2); BOOST_TEST_EQ(check_.constructions(), 6);
BOOST_TEST_EQ(check_.instances(), 8);
BOOST_TEST_EQ(check_.constructions(), 10);
BOOST_TEST(r1.first == x.emplace_hint(r1.first, // 9/3 args + duplicates with hints, different mapped value.
std::piecewise_construct,
boost::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9), emplace_value k2(9, "", 'b', 4, 5, 6, 7, 8, 9);
boost::make_tuple(15, "jkjk"))); emplace_value m2(3, "aaa", 'm');
BOOST_TEST(r1.first == x.emplace_hint(r2.first, r1 = x.emplace(std::piecewise_construct,
std::piecewise_construct, std::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9),
boost::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9), std::make_tuple(3, "aaa", 'm'));
boost::make_tuple(275, "xxx", 'm', 6))); BOOST_TEST_EQ(x.size(), 2u);
BOOST_TEST( BOOST_TEST(r1.second);
r1.first == x.emplace_hint(x.end(), std::piecewise_construct, BOOST_TEST(r1.first->first.arg_count == 9);
boost::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9), BOOST_TEST(r1.first->second.arg_count == 3);
boost::make_tuple(-10, "blah blah", '\0'))); BOOST_TEST(x.find(k2) == r1.first);
BOOST_TEST_EQ(x.size(), 2u); BOOST_TEST(x.find(k2)->second == m2);
BOOST_TEST(x.find(k2)->second == m2); BOOST_TEST_EQ(check_.instances(), 8);
BOOST_TEST_EQ(check_.instances(), 8); BOOST_TEST_EQ(check_.constructions(), 10);
BOOST_TEST_EQ(check_.constructions(), 16);
BOOST_TEST(r1.first == x.emplace_hint(r1.first, std::piecewise_construct,
std::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9),
std::make_tuple(15, "jkjk")));
BOOST_TEST(r1.first == x.emplace_hint(r2.first, std::piecewise_construct,
std::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9),
std::make_tuple(275, "xxx", 'm', 6)));
BOOST_TEST(r1.first == x.emplace_hint(x.end(), std::piecewise_construct,
std::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9),
std::make_tuple(-10, "blah blah", '\0')));
BOOST_TEST_EQ(x.size(), 2u);
BOOST_TEST(x.find(k2)->second == m2);
BOOST_TEST_EQ(check_.instances(), 8);
BOOST_TEST_EQ(check_.constructions(), 16);
}
{
test::check_instances check_;
typedef X container;
typedef typename container::iterator iterator;
typedef std::pair<iterator, bool> return_type;
container x(10);
return_type r1, r2;
// 5/8 args + duplicate
emplace_value k1(5, "", 'b', 4, 5);
emplace_value m1(8, "xxx", 'z', 4, 5, 6, 7, 8);
r1 =
x.emplace(std::piecewise_construct, boost::make_tuple(5, "", 'b', 4, 5),
boost::make_tuple(8, "xxx", 'z', 4, 5, 6, 7, 8));
BOOST_TEST_EQ(x.size(), 1u);
BOOST_TEST(r1.second);
BOOST_TEST(x.find(k1) == r1.first);
BOOST_TEST(x.find(k1)->second == m1);
BOOST_TEST_EQ(check_.instances(), 4);
BOOST_TEST_EQ(check_.constructions(), 4);
r2 =
x.emplace(std::piecewise_construct, boost::make_tuple(5, "", 'b', 4, 5),
boost::make_tuple(8, "xxx", 'z', 4, 5, 6, 7, 8));
BOOST_TEST_EQ(x.size(), 1u);
BOOST_TEST(!r2.second);
BOOST_TEST(r1.first == r2.first);
BOOST_TEST(x.find(k1)->second == m1);
BOOST_TEST_EQ(check_.instances(), 4);
// constructions could possibly be 5 if the implementation only
// constructed the key.
BOOST_TEST_EQ(check_.constructions(), 6);
// 9/3 args + duplicates with hints, different mapped value.
emplace_value k2(9, "", 'b', 4, 5, 6, 7, 8, 9);
emplace_value m2(3, "aaa", 'm');
r1 = x.emplace(std::piecewise_construct,
boost::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9),
boost::make_tuple(3, "aaa", 'm'));
BOOST_TEST_EQ(x.size(), 2u);
BOOST_TEST(r1.second);
BOOST_TEST(r1.first->first.arg_count == 9);
BOOST_TEST(r1.first->second.arg_count == 3);
BOOST_TEST(x.find(k2) == r1.first);
BOOST_TEST(x.find(k2)->second == m2);
BOOST_TEST_EQ(check_.instances(), 8);
BOOST_TEST_EQ(check_.constructions(), 10);
BOOST_TEST(r1.first == x.emplace_hint(r1.first, std::piecewise_construct,
boost::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9),
boost::make_tuple(15, "jkjk")));
BOOST_TEST(r1.first == x.emplace_hint(r2.first, std::piecewise_construct,
boost::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9),
boost::make_tuple(275, "xxx", 'm', 6)));
BOOST_TEST(r1.first == x.emplace_hint(x.end(), std::piecewise_construct,
boost::make_tuple(9, "", 'b', 4, 5, 6, 7, 8, 9),
boost::make_tuple(-10, "blah blah", '\0')));
BOOST_TEST_EQ(x.size(), 2u);
BOOST_TEST(x.find(k2)->second == m2);
BOOST_TEST_EQ(check_.instances(), 8);
BOOST_TEST_EQ(check_.constructions(), 16);
}
#endif #endif
} }

View File

@ -17,6 +17,7 @@
#include "../helpers/input_iterator.hpp" #include "../helpers/input_iterator.hpp"
#include "../helpers/helpers.hpp" #include "../helpers/helpers.hpp"
#include <boost/tuple/tuple.hpp>
#include <vector> #include <vector>
namespace insert_tests { namespace insert_tests {

View File

@ -12,6 +12,8 @@
#include "../helpers/test.hpp" #include "../helpers/test.hpp"
#include <boost/tuple/tuple.hpp>
namespace unnecessary_copy_tests { namespace unnecessary_copy_tests {
struct count_copies struct count_copies
{ {