mirror of
https://github.com/boostorg/unordered.git
synced 2025-05-09 23:23:59 +00:00
Sync from upstream.
This commit is contained in:
commit
a6a0cd0a13
@ -6,6 +6,8 @@
|
||||
#ifndef BOOST_UNORDERED_DETAIL_FOA_FLAT_MAP_TYPES_HPP
|
||||
#define BOOST_UNORDERED_DETAIL_FOA_FLAT_MAP_TYPES_HPP
|
||||
|
||||
#include <boost/unordered/detail/foa/types_constructibility.hpp>
|
||||
|
||||
#include <boost/core/allocator_access.hpp>
|
||||
|
||||
namespace boost {
|
||||
@ -25,6 +27,9 @@ namespace boost {
|
||||
|
||||
using element_type = value_type;
|
||||
|
||||
using types = flat_map_types<Key, T>;
|
||||
using constructibility_checker = map_types_constructibility<types>;
|
||||
|
||||
static value_type& value_from(element_type& x) { return x; }
|
||||
|
||||
template <class K, class V>
|
||||
@ -48,18 +53,21 @@ namespace boost {
|
||||
template <class A, class... Args>
|
||||
static void construct(A& al, init_type* p, Args&&... args)
|
||||
{
|
||||
constructibility_checker::check(al, p, std::forward<Args>(args)...);
|
||||
boost::allocator_construct(al, p, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <class A, class... Args>
|
||||
static void construct(A& al, value_type* p, Args&&... args)
|
||||
{
|
||||
constructibility_checker::check(al, p, std::forward<Args>(args)...);
|
||||
boost::allocator_construct(al, p, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <class A, class... Args>
|
||||
static void construct(A& al, key_type* p, Args&&... args)
|
||||
{
|
||||
constructibility_checker::check(al, p, std::forward<Args>(args)...);
|
||||
boost::allocator_construct(al, p, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
@ -79,8 +87,8 @@ namespace boost {
|
||||
}
|
||||
};
|
||||
} // namespace foa
|
||||
} // namespace detail
|
||||
} // namespace unordered
|
||||
} // namespace detail
|
||||
} // namespace unordered
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_UNORDERED_DETAIL_FOA_FLAT_MAP_TYPES_HPP
|
||||
|
@ -5,6 +5,8 @@
|
||||
#ifndef BOOST_UNORDERED_DETAIL_FOA_FLAT_SET_TYPES_HPP
|
||||
#define BOOST_UNORDERED_DETAIL_FOA_FLAT_SET_TYPES_HPP
|
||||
|
||||
#include <boost/unordered/detail/foa/types_constructibility.hpp>
|
||||
|
||||
#include <boost/core/allocator_access.hpp>
|
||||
|
||||
namespace boost {
|
||||
@ -21,6 +23,9 @@ namespace boost {
|
||||
|
||||
using element_type = value_type;
|
||||
|
||||
using types = flat_set_types<Key>;
|
||||
using constructibility_checker = set_types_constructibility<types>;
|
||||
|
||||
static Key& value_from(element_type& x) { return x; }
|
||||
|
||||
static element_type&& move(element_type& x) { return std::move(x); }
|
||||
@ -28,6 +33,7 @@ namespace boost {
|
||||
template <class A, class... Args>
|
||||
static void construct(A& al, value_type* p, Args&&... args)
|
||||
{
|
||||
constructibility_checker::check(al, p, std::forward<Args>(args)...);
|
||||
boost::allocator_construct(al, p, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
@ -37,8 +43,8 @@ namespace boost {
|
||||
}
|
||||
};
|
||||
} // namespace foa
|
||||
} // namespace detail
|
||||
} // namespace unordered
|
||||
} // namespace detail
|
||||
} // namespace unordered
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_UNORDERED_DETAIL_FOA_FLAT_SET_TYPES_HPP
|
||||
|
@ -7,6 +7,8 @@
|
||||
#define BOOST_UNORDERED_DETAIL_FOA_NODE_MAP_TYPES_HPP
|
||||
|
||||
#include <boost/unordered/detail/foa/element_type.hpp>
|
||||
#include <boost/unordered/detail/foa/types_constructibility.hpp>
|
||||
#include <boost/unordered/detail/type_traits.hpp>
|
||||
|
||||
#include <boost/core/allocator_access.hpp>
|
||||
#include <boost/core/no_exceptions_support.hpp>
|
||||
@ -29,6 +31,9 @@ namespace boost {
|
||||
|
||||
using element_type = foa::element_type<value_type, VoidPtr>;
|
||||
|
||||
using types = node_map_types<Key, T, VoidPtr>;
|
||||
using constructibility_checker = map_types_constructibility<types>;
|
||||
|
||||
static value_type& value_from(element_type const& x)
|
||||
{
|
||||
return *(x.p);
|
||||
@ -68,24 +73,27 @@ namespace boost {
|
||||
static void construct(
|
||||
A& al, element_type* p, element_type const& copy)
|
||||
{
|
||||
construct(al, p, *copy.p);
|
||||
construct(al, p, detail::as_const(*copy.p));
|
||||
}
|
||||
|
||||
template <class A, class... Args>
|
||||
static void construct(A& al, init_type* p, Args&&... args)
|
||||
{
|
||||
constructibility_checker::check(al, p, std::forward<Args>(args)...);
|
||||
boost::allocator_construct(al, p, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <class A, class... Args>
|
||||
static void construct(A& al, value_type* p, Args&&... args)
|
||||
{
|
||||
constructibility_checker::check(al, p, std::forward<Args>(args)...);
|
||||
boost::allocator_construct(al, p, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
template <class A, class... Args>
|
||||
static void construct(A& al, key_type* p, Args&&... args)
|
||||
{
|
||||
constructibility_checker::check(al, p, std::forward<Args>(args)...);
|
||||
boost::allocator_construct(al, p, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
@ -95,8 +103,11 @@ namespace boost {
|
||||
p->p = boost::allocator_allocate(al, 1);
|
||||
BOOST_TRY
|
||||
{
|
||||
auto address = boost::to_address(p->p);
|
||||
constructibility_checker::check(
|
||||
al, address, std::forward<Args>(args)...);
|
||||
boost::allocator_construct(
|
||||
al, boost::to_address(p->p), std::forward<Args>(args)...);
|
||||
al, address, std::forward<Args>(args)...);
|
||||
}
|
||||
BOOST_CATCH(...)
|
||||
{
|
||||
@ -132,8 +143,8 @@ namespace boost {
|
||||
};
|
||||
|
||||
} // namespace foa
|
||||
} // namespace detail
|
||||
} // namespace unordered
|
||||
} // namespace detail
|
||||
} // namespace unordered
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_UNORDERED_DETAIL_FOA_NODE_MAP_TYPES_HPP
|
||||
|
@ -6,6 +6,8 @@
|
||||
#define BOOST_UNORDERED_DETAIL_FOA_NODE_SET_TYPES_HPP
|
||||
|
||||
#include <boost/unordered/detail/foa/element_type.hpp>
|
||||
#include <boost/unordered/detail/foa/types_constructibility.hpp>
|
||||
#include <boost/unordered/detail/type_traits.hpp>
|
||||
|
||||
#include <boost/core/allocator_access.hpp>
|
||||
#include <boost/core/no_exceptions_support.hpp>
|
||||
@ -26,6 +28,9 @@ namespace boost {
|
||||
|
||||
using element_type = foa::element_type<value_type, VoidPtr>;
|
||||
|
||||
using types = node_set_types<Key, VoidPtr>;
|
||||
using constructibility_checker = set_types_constructibility<types>;
|
||||
|
||||
static value_type& value_from(element_type const& x) { return *x.p; }
|
||||
static Key const& extract(element_type const& k) { return *k.p; }
|
||||
static element_type&& move(element_type& x) { return std::move(x); }
|
||||
@ -35,7 +40,7 @@ namespace boost {
|
||||
static void construct(
|
||||
A& al, element_type* p, element_type const& copy)
|
||||
{
|
||||
construct(al, p, *copy.p);
|
||||
construct(al, p, detail::as_const(*copy.p));
|
||||
}
|
||||
|
||||
template <typename Allocator>
|
||||
@ -49,6 +54,7 @@ namespace boost {
|
||||
template <class A, class... Args>
|
||||
static void construct(A& al, value_type* p, Args&&... args)
|
||||
{
|
||||
constructibility_checker::check(al, p, std::forward<Args>(args)...);
|
||||
boost::allocator_construct(al, p, std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
@ -58,8 +64,11 @@ namespace boost {
|
||||
p->p = boost::allocator_allocate(al, 1);
|
||||
BOOST_TRY
|
||||
{
|
||||
auto address = boost::to_address(p->p);
|
||||
constructibility_checker::check(
|
||||
al, address, std::forward<Args>(args)...);
|
||||
boost::allocator_construct(
|
||||
al, boost::to_address(p->p), std::forward<Args>(args)...);
|
||||
al, address, std::forward<Args>(args)...);
|
||||
}
|
||||
BOOST_CATCH(...)
|
||||
{
|
||||
@ -85,8 +94,8 @@ namespace boost {
|
||||
};
|
||||
|
||||
} // namespace foa
|
||||
} // namespace detail
|
||||
} // namespace unordered
|
||||
} // namespace detail
|
||||
} // namespace unordered
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_UNORDERED_DETAIL_FOA_NODE_SET_TYPES_HPP
|
||||
|
172
include/boost/unordered/detail/foa/types_constructibility.hpp
Normal file
172
include/boost/unordered/detail/foa/types_constructibility.hpp
Normal file
@ -0,0 +1,172 @@
|
||||
// Copyright (C) 2024 Braden Ganetsky
|
||||
// Distributed under the Boost Software License, Version 1.0. (See accompanying
|
||||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
|
||||
|
||||
#ifndef BOOST_UNORDERED_DETAIL_FOA_TYPES_CONSTRUCTIBILITY_HPP
|
||||
#define BOOST_UNORDERED_DETAIL_FOA_TYPES_CONSTRUCTIBILITY_HPP
|
||||
|
||||
#include <memory>
|
||||
#include <tuple>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
namespace boost {
|
||||
namespace unordered {
|
||||
namespace detail {
|
||||
namespace foa {
|
||||
template <class Key, class... Args> struct check_key_type_t
|
||||
{
|
||||
static_assert(std::is_constructible<Key, Args...>::value,
|
||||
"key_type must be constructible from Args");
|
||||
};
|
||||
template <class Key> struct check_key_type_t<Key>
|
||||
{
|
||||
static_assert(std::is_constructible<Key>::value,
|
||||
"key_type must be default constructible");
|
||||
};
|
||||
template <class Key> struct check_key_type_t<Key, const Key&>
|
||||
{
|
||||
static_assert(std::is_constructible<Key, const Key&>::value,
|
||||
"key_type must be copy constructible");
|
||||
};
|
||||
template <class Key> struct check_key_type_t<Key, Key&&>
|
||||
{
|
||||
static_assert(std::is_constructible<Key, Key&&>::value,
|
||||
"key_type must be move constructible");
|
||||
};
|
||||
|
||||
template <class Mapped, class... Args> struct check_mapped_type_t
|
||||
{
|
||||
static_assert(std::is_constructible<Mapped, Args...>::value,
|
||||
"mapped_type must be constructible from Args");
|
||||
};
|
||||
template <class Mapped> struct check_mapped_type_t<Mapped>
|
||||
{
|
||||
static_assert(std::is_constructible<Mapped>::value,
|
||||
"mapped_type must be default constructible");
|
||||
};
|
||||
template <class Mapped>
|
||||
struct check_mapped_type_t<Mapped, const Mapped&>
|
||||
{
|
||||
static_assert(std::is_constructible<Mapped, const Mapped&>::value,
|
||||
"mapped_type must be copy constructible");
|
||||
};
|
||||
template <class Mapped> struct check_mapped_type_t<Mapped, Mapped&&>
|
||||
{
|
||||
static_assert(std::is_constructible<Mapped, Mapped&&>::value,
|
||||
"mapped_type must be move constructible");
|
||||
};
|
||||
|
||||
template <class TypePolicy> struct map_types_constructibility
|
||||
{
|
||||
using key_type = typename TypePolicy::key_type;
|
||||
using mapped_type = typename TypePolicy::mapped_type;
|
||||
using init_type = typename TypePolicy::init_type;
|
||||
using value_type = typename TypePolicy::value_type;
|
||||
|
||||
template <class A, class X, class... Args>
|
||||
static void check(A&, X*, Args&&...)
|
||||
{
|
||||
// Pass through, as we cannot say anything about a general allocator
|
||||
}
|
||||
|
||||
template <class... Args> static void check_key_type()
|
||||
{
|
||||
(void)check_key_type_t<key_type, Args...>{};
|
||||
}
|
||||
template <class... Args> static void check_mapped_type()
|
||||
{
|
||||
(void)check_mapped_type_t<mapped_type, Args...>{};
|
||||
}
|
||||
|
||||
template <class Arg>
|
||||
static void check(std::allocator<value_type>&, key_type*, Arg&&)
|
||||
{
|
||||
check_key_type<Arg&&>();
|
||||
}
|
||||
|
||||
template <class Arg1, class Arg2>
|
||||
static void check(
|
||||
std::allocator<value_type>&, value_type*, Arg1&&, Arg2&&)
|
||||
{
|
||||
check_key_type<Arg1&&>();
|
||||
check_mapped_type<Arg2&&>();
|
||||
}
|
||||
template <class Arg1, class Arg2>
|
||||
static void check(std::allocator<value_type>&, value_type*,
|
||||
const std::pair<Arg1, Arg2>&)
|
||||
{
|
||||
check_key_type<const Arg1&>();
|
||||
check_mapped_type<const Arg2&>();
|
||||
}
|
||||
template <class Arg1, class Arg2>
|
||||
static void check(
|
||||
std::allocator<value_type>&, value_type*, std::pair<Arg1, Arg2>&&)
|
||||
{
|
||||
check_key_type<Arg1&&>();
|
||||
check_mapped_type<Arg2&&>();
|
||||
}
|
||||
template <class... Args1, class... Args2>
|
||||
static void check(std::allocator<value_type>&, value_type*,
|
||||
std::piecewise_construct_t, std::tuple<Args1...>&&,
|
||||
std::tuple<Args2...>&&)
|
||||
{
|
||||
check_key_type<Args1&&...>();
|
||||
check_mapped_type<Args2&&...>();
|
||||
}
|
||||
|
||||
template <class Arg1, class Arg2>
|
||||
static void check(
|
||||
std::allocator<value_type>&, init_type*, Arg1&&, Arg2&&)
|
||||
{
|
||||
check_key_type<Arg1&&>();
|
||||
check_mapped_type<Arg2&&>();
|
||||
}
|
||||
template <class Arg1, class Arg2>
|
||||
static void check(std::allocator<value_type>&, init_type*,
|
||||
const std::pair<Arg1, Arg2>&)
|
||||
{
|
||||
check_key_type<const Arg1&>();
|
||||
check_mapped_type<const Arg2&>();
|
||||
}
|
||||
template <class Arg1, class Arg2>
|
||||
static void check(
|
||||
std::allocator<value_type>&, init_type*, std::pair<Arg1, Arg2>&&)
|
||||
{
|
||||
check_key_type<Arg1&&>();
|
||||
check_mapped_type<Arg2&&>();
|
||||
}
|
||||
template <class... Args1, class... Args2>
|
||||
static void check(std::allocator<value_type>&, init_type*,
|
||||
std::piecewise_construct_t, std::tuple<Args1...>&&,
|
||||
std::tuple<Args2...>&&)
|
||||
{
|
||||
check_key_type<Args1&&...>();
|
||||
check_mapped_type<Args2&&...>();
|
||||
}
|
||||
};
|
||||
|
||||
template <class TypePolicy> struct set_types_constructibility
|
||||
{
|
||||
using key_type = typename TypePolicy::key_type;
|
||||
using value_type = typename TypePolicy::value_type;
|
||||
static_assert(std::is_same<key_type, value_type>::value, "");
|
||||
|
||||
template <class A, class X, class... Args>
|
||||
static void check(A&, X*, Args&&...)
|
||||
{
|
||||
// Pass through, as we cannot say anything about a general allocator
|
||||
}
|
||||
|
||||
template <class... Args>
|
||||
static void check(std::allocator<value_type>&, key_type*, Args&&...)
|
||||
{
|
||||
(void)check_key_type_t<key_type, Args&&...>{};
|
||||
}
|
||||
};
|
||||
} // namespace foa
|
||||
} // namespace detail
|
||||
} // namespace unordered
|
||||
} // namespace boost
|
||||
|
||||
#endif // BOOST_UNORDERED_DETAIL_FOA_TYPES_CONSTRUCTIBILITY_HPP
|
@ -219,6 +219,17 @@ namespace boost {
|
||||
using iter_to_alloc_t =
|
||||
typename std::pair<iter_key_t<T> const, iter_val_t<T> >;
|
||||
#endif
|
||||
|
||||
#if BOOST_CXX_VERSION < 201703L
|
||||
template <class T>
|
||||
constexpr typename std::add_const<T>::type& as_const(T& t) noexcept
|
||||
{
|
||||
return t;
|
||||
}
|
||||
template <class T> void as_const(const T&&) = delete;
|
||||
#else
|
||||
using std::as_const;
|
||||
#endif
|
||||
} // namespace detail
|
||||
} // namespace unordered
|
||||
} // namespace boost
|
||||
|
@ -198,7 +198,7 @@ namespace boost {
|
||||
template <class... Args> std::pair<iterator, bool> emplace(Args&&... args)
|
||||
{
|
||||
return table_.emplace_unique(
|
||||
table::extractor::extract(std::forward<Args>(args)...),
|
||||
table::extractor::extract(detail::as_const(args)...),
|
||||
std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
@ -206,7 +206,7 @@ namespace boost {
|
||||
iterator emplace_hint(const_iterator hint, Args&&... args)
|
||||
{
|
||||
return table_.emplace_hint_unique(hint,
|
||||
table::extractor::extract(std::forward<Args>(args)...),
|
||||
table::extractor::extract(detail::as_const(args)...),
|
||||
std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
|
@ -194,7 +194,7 @@ namespace boost {
|
||||
template <class... Args> std::pair<iterator, bool> emplace(Args&&... args)
|
||||
{
|
||||
return table_.emplace_unique(
|
||||
table::extractor::extract(std::forward<Args>(args)...),
|
||||
table::extractor::extract(detail::as_const(args)...),
|
||||
std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
@ -202,7 +202,7 @@ namespace boost {
|
||||
iterator emplace_hint(const_iterator hint, Args&&... args)
|
||||
{
|
||||
return table_.emplace_hint_unique(hint,
|
||||
table::extractor::extract(std::forward<Args>(args)...),
|
||||
table::extractor::extract(detail::as_const(args)...),
|
||||
std::forward<Args>(args)...);
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user