mirror of
https://github.com/boostorg/unordered.git
synced 2025-07-30 03:17:15 +02:00
Refactor type policies used by containers into their own dedicated headers
This commit is contained in:
@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
#include <boost/unordered/concurrent_flat_map_fwd.hpp>
|
#include <boost/unordered/concurrent_flat_map_fwd.hpp>
|
||||||
#include <boost/unordered/detail/foa/concurrent_table.hpp>
|
#include <boost/unordered/detail/foa/concurrent_table.hpp>
|
||||||
|
#include <boost/unordered/detail/foa/flat_map_types.hpp>
|
||||||
#include <boost/unordered/detail/type_traits.hpp>
|
#include <boost/unordered/detail/type_traits.hpp>
|
||||||
|
|
||||||
#include <boost/container_hash/hash.hpp>
|
#include <boost/container_hash/hash.hpp>
|
||||||
@ -67,7 +68,6 @@
|
|||||||
namespace boost {
|
namespace boost {
|
||||||
namespace unordered {
|
namespace unordered {
|
||||||
namespace detail {
|
namespace detail {
|
||||||
|
|
||||||
template <class F, class... Args>
|
template <class F, class... Args>
|
||||||
struct is_invocable
|
struct is_invocable
|
||||||
: std::is_constructible<std::function<void(Args...)>,
|
: std::is_constructible<std::function<void(Args...)>,
|
||||||
@ -75,60 +75,6 @@ namespace boost {
|
|||||||
{
|
{
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class Key, class T> struct concurrent_map_types
|
|
||||||
{
|
|
||||||
using key_type = Key;
|
|
||||||
using raw_key_type = typename std::remove_const<Key>::type;
|
|
||||||
using raw_mapped_type = typename std::remove_const<T>::type;
|
|
||||||
|
|
||||||
using init_type = std::pair<raw_key_type, raw_mapped_type>;
|
|
||||||
using moved_type = std::pair<raw_key_type&&, raw_mapped_type&&>;
|
|
||||||
using value_type = std::pair<Key const, T>;
|
|
||||||
|
|
||||||
using element_type = value_type;
|
|
||||||
|
|
||||||
static value_type& value_from(element_type& x) { return x; }
|
|
||||||
|
|
||||||
template <class K, class V>
|
|
||||||
static raw_key_type const& extract(std::pair<K, V> const& kv)
|
|
||||||
{
|
|
||||||
return kv.first;
|
|
||||||
}
|
|
||||||
|
|
||||||
static moved_type move(init_type& x)
|
|
||||||
{
|
|
||||||
return {std::move(x.first), std::move(x.second)};
|
|
||||||
}
|
|
||||||
|
|
||||||
static moved_type move(element_type& x)
|
|
||||||
{
|
|
||||||
// TODO: we probably need to launder here
|
|
||||||
return {std::move(const_cast<raw_key_type&>(x.first)),
|
|
||||||
std::move(const_cast<raw_mapped_type&>(x.second))};
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class A, class... Args>
|
|
||||||
static void construct(A& al, init_type* p, 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)
|
|
||||||
{
|
|
||||||
boost::allocator_construct(al, p, std::forward<Args>(args)...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class A> static void destroy(A& al, init_type* p) noexcept
|
|
||||||
{
|
|
||||||
boost::allocator_destroy(al, p);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class A> static void destroy(A& al, value_type* p) noexcept
|
|
||||||
{
|
|
||||||
boost::allocator_destroy(al, p);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} // namespace detail
|
} // namespace detail
|
||||||
|
|
||||||
template <class Key, class T, class Hash, class Pred, class Allocator>
|
template <class Key, class T, class Hash, class Pred, class Allocator>
|
||||||
@ -139,7 +85,7 @@ namespace boost {
|
|||||||
class Allocator2>
|
class Allocator2>
|
||||||
friend class concurrent_flat_map;
|
friend class concurrent_flat_map;
|
||||||
|
|
||||||
using type_policy = detail::concurrent_map_types<Key, T>;
|
using type_policy = detail::foa::flat_map_types<Key, T>;
|
||||||
|
|
||||||
detail::foa::concurrent_table<type_policy, Hash, Pred, Allocator> table_;
|
detail::foa::concurrent_table<type_policy, Hash, Pred, Allocator> table_;
|
||||||
|
|
||||||
|
73
include/boost/unordered/detail/foa/flat_map_types.hpp
Normal file
73
include/boost/unordered/detail/foa/flat_map_types.hpp
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
// Copyright (C) 2023 Christian Mazakas
|
||||||
|
// 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_FLAT_MAP_TYPES_HPP
|
||||||
|
#define BOOST_UNORDERED_DETAIL_FOA_FLAT_MAP_TYPES_HPP
|
||||||
|
|
||||||
|
#include <boost/core/allocator_access.hpp>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
namespace unordered {
|
||||||
|
namespace detail {
|
||||||
|
namespace foa {
|
||||||
|
template <class Key, class T> struct flat_map_types
|
||||||
|
{
|
||||||
|
using key_type = Key;
|
||||||
|
using raw_key_type = typename std::remove_const<Key>::type;
|
||||||
|
using raw_mapped_type = typename std::remove_const<T>::type;
|
||||||
|
|
||||||
|
using init_type = std::pair<raw_key_type, raw_mapped_type>;
|
||||||
|
using moved_type = std::pair<raw_key_type&&, raw_mapped_type&&>;
|
||||||
|
using value_type = std::pair<Key const, T>;
|
||||||
|
|
||||||
|
using element_type = value_type;
|
||||||
|
|
||||||
|
static value_type& value_from(element_type& x) { return x; }
|
||||||
|
|
||||||
|
template <class K, class V>
|
||||||
|
static raw_key_type const& extract(std::pair<K, V> const& kv)
|
||||||
|
{
|
||||||
|
return kv.first;
|
||||||
|
}
|
||||||
|
|
||||||
|
static moved_type move(init_type& x)
|
||||||
|
{
|
||||||
|
return {std::move(x.first), std::move(x.second)};
|
||||||
|
}
|
||||||
|
|
||||||
|
static moved_type move(element_type& x)
|
||||||
|
{
|
||||||
|
// TODO: we probably need to launder here
|
||||||
|
return {std::move(const_cast<raw_key_type&>(x.first)),
|
||||||
|
std::move(const_cast<raw_mapped_type&>(x.second))};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class A, class... Args>
|
||||||
|
static void construct(A& al, init_type* p, 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)
|
||||||
|
{
|
||||||
|
boost::allocator_construct(al, p, std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class A> static void destroy(A& al, init_type* p) noexcept
|
||||||
|
{
|
||||||
|
boost::allocator_destroy(al, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class A> static void destroy(A& al, value_type* p) noexcept
|
||||||
|
{
|
||||||
|
boost::allocator_destroy(al, p);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace foa
|
||||||
|
} // namespace detail
|
||||||
|
} // namespace unordered
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // BOOST_UNORDERED_DETAIL_FOA_FLAT_MAP_TYPES_HPP
|
44
include/boost/unordered/detail/foa/flat_set_types.hpp
Normal file
44
include/boost/unordered/detail/foa/flat_set_types.hpp
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
// Copyright (C) 2023 Christian Mazakas
|
||||||
|
// 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_FLAT_SET_TYPES_HPP
|
||||||
|
#define BOOST_UNORDERED_DETAIL_FOA_FLAT_SET_TYPES_HPP
|
||||||
|
|
||||||
|
#include <boost/core/allocator_access.hpp>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
namespace unordered {
|
||||||
|
namespace detail {
|
||||||
|
namespace foa {
|
||||||
|
template <class Key> struct flat_set_types
|
||||||
|
{
|
||||||
|
using key_type = Key;
|
||||||
|
using init_type = Key;
|
||||||
|
using value_type = Key;
|
||||||
|
|
||||||
|
static Key const& extract(value_type const& key) { return key; }
|
||||||
|
|
||||||
|
using element_type = value_type;
|
||||||
|
|
||||||
|
static Key& value_from(element_type& x) { return x; }
|
||||||
|
|
||||||
|
static element_type&& move(element_type& x) { return std::move(x); }
|
||||||
|
|
||||||
|
template <class A, class... Args>
|
||||||
|
static void construct(A& al, value_type* p, Args&&... args)
|
||||||
|
{
|
||||||
|
boost::allocator_construct(al, p, std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class A> static void destroy(A& al, value_type* p) noexcept
|
||||||
|
{
|
||||||
|
boost::allocator_destroy(al, p);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} // namespace foa
|
||||||
|
} // namespace detail
|
||||||
|
} // namespace unordered
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // BOOST_UNORDERED_DETAIL_FOA_FLAT_SET_TYPES_HPP
|
131
include/boost/unordered/detail/foa/node_map_types.hpp
Normal file
131
include/boost/unordered/detail/foa/node_map_types.hpp
Normal file
@ -0,0 +1,131 @@
|
|||||||
|
// Copyright (C) 2023 Christian Mazakas
|
||||||
|
// 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_NODE_MAP_TYPES_HPP
|
||||||
|
#define BOOST_UNORDERED_DETAIL_FOA_NODE_MAP_TYPES_HPP
|
||||||
|
|
||||||
|
#include <boost/core/allocator_access.hpp>
|
||||||
|
#include <boost/core/pointer_traits.hpp>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
namespace unordered {
|
||||||
|
namespace detail {
|
||||||
|
namespace foa {
|
||||||
|
template <class Key, class T> struct node_map_types
|
||||||
|
{
|
||||||
|
using key_type = Key;
|
||||||
|
using mapped_type = T;
|
||||||
|
using raw_key_type = typename std::remove_const<Key>::type;
|
||||||
|
using raw_mapped_type = typename std::remove_const<T>::type;
|
||||||
|
|
||||||
|
using init_type = std::pair<raw_key_type, raw_mapped_type>;
|
||||||
|
using value_type = std::pair<Key const, T>;
|
||||||
|
using moved_type = std::pair<raw_key_type&&, raw_mapped_type&&>;
|
||||||
|
|
||||||
|
using element_type = foa::element_type<value_type>;
|
||||||
|
|
||||||
|
static value_type& value_from(element_type const& x)
|
||||||
|
{
|
||||||
|
return *(x.p);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class K, class V>
|
||||||
|
static raw_key_type const& extract(std::pair<K, V> const& kv)
|
||||||
|
{
|
||||||
|
return kv.first;
|
||||||
|
}
|
||||||
|
|
||||||
|
static raw_key_type const& extract(element_type const& kv)
|
||||||
|
{
|
||||||
|
return kv.p->first;
|
||||||
|
}
|
||||||
|
|
||||||
|
static element_type&& move(element_type& x) { return std::move(x); }
|
||||||
|
static moved_type move(init_type& x)
|
||||||
|
{
|
||||||
|
return {std::move(x.first), std::move(x.second)};
|
||||||
|
}
|
||||||
|
|
||||||
|
static moved_type move(value_type& x)
|
||||||
|
{
|
||||||
|
return {std::move(const_cast<raw_key_type&>(x.first)),
|
||||||
|
std::move(const_cast<raw_mapped_type&>(x.second))};
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class A>
|
||||||
|
static void construct(A&, element_type* p, element_type&& x) noexcept
|
||||||
|
{
|
||||||
|
p->p = x.p;
|
||||||
|
x.p = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class A>
|
||||||
|
static void construct(
|
||||||
|
A& al, element_type* p, element_type const& copy)
|
||||||
|
{
|
||||||
|
construct(al, p, *copy.p);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class A, class... Args>
|
||||||
|
static void construct(A& al, init_type* p, 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)
|
||||||
|
{
|
||||||
|
boost::allocator_construct(al, p, std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class A, class... Args>
|
||||||
|
static void construct(A& al, element_type* p, Args&&... args)
|
||||||
|
{
|
||||||
|
p->p = boost::to_address(boost::allocator_allocate(al, 1));
|
||||||
|
BOOST_TRY
|
||||||
|
{
|
||||||
|
boost::allocator_construct(al, p->p, std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
BOOST_CATCH(...)
|
||||||
|
{
|
||||||
|
using pointer_type = typename boost::allocator_pointer<A>::type;
|
||||||
|
using pointer_traits = boost::pointer_traits<pointer_type>;
|
||||||
|
|
||||||
|
boost::allocator_deallocate(
|
||||||
|
al, pointer_traits::pointer_to(*(p->p)), 1);
|
||||||
|
BOOST_RETHROW
|
||||||
|
}
|
||||||
|
BOOST_CATCH_END
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class A> static void destroy(A& al, value_type* p) noexcept
|
||||||
|
{
|
||||||
|
boost::allocator_destroy(al, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class A> static void destroy(A& al, init_type* p) noexcept
|
||||||
|
{
|
||||||
|
boost::allocator_destroy(al, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class A>
|
||||||
|
static void destroy(A& al, element_type* p) noexcept
|
||||||
|
{
|
||||||
|
if (p->p) {
|
||||||
|
using pointer_type = typename boost::allocator_pointer<A>::type;
|
||||||
|
using pointer_traits = boost::pointer_traits<pointer_type>;
|
||||||
|
|
||||||
|
destroy(al, p->p);
|
||||||
|
boost::allocator_deallocate(
|
||||||
|
al, pointer_traits::pointer_to(*(p->p)), 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace foa
|
||||||
|
} // namespace detail
|
||||||
|
} // namespace unordered
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // BOOST_UNORDERED_DETAIL_FOA_NODE_MAP_TYPES_HPP
|
94
include/boost/unordered/detail/foa/node_set_types.hpp
Normal file
94
include/boost/unordered/detail/foa/node_set_types.hpp
Normal file
@ -0,0 +1,94 @@
|
|||||||
|
// Copyright (C) 2023 Christian Mazakas
|
||||||
|
// 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_NODE_SET_TYPES_HPP
|
||||||
|
#define BOOST_UNORDERED_DETAIL_FOA_NODE_SET_TYPES_HPP
|
||||||
|
|
||||||
|
#include <boost/core/allocator_access.hpp>
|
||||||
|
#include <boost/core/pointer_traits.hpp>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
namespace unordered {
|
||||||
|
namespace detail {
|
||||||
|
namespace foa {
|
||||||
|
|
||||||
|
template <class Key> struct node_set_types
|
||||||
|
{
|
||||||
|
using key_type = Key;
|
||||||
|
using init_type = Key;
|
||||||
|
using value_type = Key;
|
||||||
|
|
||||||
|
static Key const& extract(value_type const& key) { return key; }
|
||||||
|
|
||||||
|
using element_type = foa::element_type<value_type>;
|
||||||
|
|
||||||
|
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); }
|
||||||
|
static value_type&& move(value_type& x) { return std::move(x); }
|
||||||
|
|
||||||
|
template <class A>
|
||||||
|
static void construct(
|
||||||
|
A& al, element_type* p, element_type const& copy)
|
||||||
|
{
|
||||||
|
construct(al, p, *copy.p);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename Allocator>
|
||||||
|
static void construct(
|
||||||
|
Allocator&, element_type* p, element_type&& x) noexcept
|
||||||
|
{
|
||||||
|
p->p = x.p;
|
||||||
|
x.p = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class A, class... Args>
|
||||||
|
static void construct(A& al, value_type* p, Args&&... args)
|
||||||
|
{
|
||||||
|
boost::allocator_construct(al, p, std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class A, class... Args>
|
||||||
|
static void construct(A& al, element_type* p, Args&&... args)
|
||||||
|
{
|
||||||
|
p->p = boost::to_address(boost::allocator_allocate(al, 1));
|
||||||
|
BOOST_TRY
|
||||||
|
{
|
||||||
|
boost::allocator_construct(al, p->p, std::forward<Args>(args)...);
|
||||||
|
}
|
||||||
|
BOOST_CATCH(...)
|
||||||
|
{
|
||||||
|
boost::allocator_deallocate(al,
|
||||||
|
boost::pointer_traits<typename boost::allocator_pointer<
|
||||||
|
A>::type>::pointer_to(*p->p),
|
||||||
|
1);
|
||||||
|
BOOST_RETHROW
|
||||||
|
}
|
||||||
|
BOOST_CATCH_END
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class A> static void destroy(A& al, value_type* p) noexcept
|
||||||
|
{
|
||||||
|
boost::allocator_destroy(al, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class A>
|
||||||
|
static void destroy(A& al, element_type* p) noexcept
|
||||||
|
{
|
||||||
|
if (p->p) {
|
||||||
|
destroy(al, p->p);
|
||||||
|
boost::allocator_deallocate(al,
|
||||||
|
boost::pointer_traits<typename boost::allocator_pointer<
|
||||||
|
A>::type>::pointer_to(*(p->p)),
|
||||||
|
1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace foa
|
||||||
|
} // namespace detail
|
||||||
|
} // namespace unordered
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // BOOST_UNORDERED_DETAIL_FOA_NODE_SET_TYPES_HPP
|
@ -10,6 +10,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <boost/unordered/detail/foa/flat_map_types.hpp>
|
||||||
#include <boost/unordered/detail/foa/table.hpp>
|
#include <boost/unordered/detail/foa/table.hpp>
|
||||||
#include <boost/unordered/detail/type_traits.hpp>
|
#include <boost/unordered/detail/type_traits.hpp>
|
||||||
#include <boost/unordered/unordered_flat_map_fwd.hpp>
|
#include <boost/unordered/unordered_flat_map_fwd.hpp>
|
||||||
@ -32,67 +33,10 @@ namespace boost {
|
|||||||
#pragma warning(disable : 4714) /* marked as __forceinline not inlined */
|
#pragma warning(disable : 4714) /* marked as __forceinline not inlined */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
template <class Key, class T> struct flat_map_types
|
|
||||||
{
|
|
||||||
using key_type = Key;
|
|
||||||
using raw_key_type = typename std::remove_const<Key>::type;
|
|
||||||
using raw_mapped_type = typename std::remove_const<T>::type;
|
|
||||||
|
|
||||||
using init_type = std::pair<raw_key_type, raw_mapped_type>;
|
|
||||||
using moved_type = std::pair<raw_key_type&&, raw_mapped_type&&>;
|
|
||||||
using value_type = std::pair<Key const, T>;
|
|
||||||
|
|
||||||
using element_type = value_type;
|
|
||||||
|
|
||||||
static value_type& value_from(element_type& x) { return x; }
|
|
||||||
|
|
||||||
template <class K, class V>
|
|
||||||
static raw_key_type const& extract(std::pair<K, V> const& kv)
|
|
||||||
{
|
|
||||||
return kv.first;
|
|
||||||
}
|
|
||||||
|
|
||||||
static moved_type move(init_type& x)
|
|
||||||
{
|
|
||||||
return {std::move(x.first), std::move(x.second)};
|
|
||||||
}
|
|
||||||
|
|
||||||
static moved_type move(element_type& x)
|
|
||||||
{
|
|
||||||
// TODO: we probably need to launder here
|
|
||||||
return {std::move(const_cast<raw_key_type&>(x.first)),
|
|
||||||
std::move(const_cast<raw_mapped_type&>(x.second))};
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class A, class... Args>
|
|
||||||
static void construct(A& al, init_type* p, 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)
|
|
||||||
{
|
|
||||||
boost::allocator_construct(al, p, std::forward<Args>(args)...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class A> static void destroy(A& al, init_type* p) noexcept
|
|
||||||
{
|
|
||||||
boost::allocator_destroy(al, p);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class A> static void destroy(A& al, value_type* p) noexcept
|
|
||||||
{
|
|
||||||
boost::allocator_destroy(al, p);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
template <class Key, class T, class Hash, class KeyEqual, class Allocator>
|
template <class Key, class T, class Hash, class KeyEqual, class Allocator>
|
||||||
class unordered_flat_map
|
class unordered_flat_map
|
||||||
{
|
{
|
||||||
using map_types = detail::flat_map_types<Key, T>;
|
using map_types = detail::foa::flat_map_types<Key, T>;
|
||||||
|
|
||||||
using table_type = detail::foa::table<map_types, Hash, KeyEqual,
|
using table_type = detail::foa::table<map_types, Hash, KeyEqual,
|
||||||
typename boost::allocator_rebind<Allocator,
|
typename boost::allocator_rebind<Allocator,
|
||||||
@ -101,8 +45,7 @@ namespace boost {
|
|||||||
table_type table_;
|
table_type table_;
|
||||||
|
|
||||||
template <class K, class V, class H, class KE, class A>
|
template <class K, class V, class H, class KE, class A>
|
||||||
bool friend operator==(
|
bool friend operator==(unordered_flat_map<K, V, H, KE, A> const& lhs,
|
||||||
unordered_flat_map<K, V, H, KE, A> const& lhs,
|
|
||||||
unordered_flat_map<K, V, H, KE, A> const& rhs);
|
unordered_flat_map<K, V, H, KE, A> const& rhs);
|
||||||
|
|
||||||
template <class K, class V, class H, class KE, class A, class Pred>
|
template <class K, class V, class H, class KE, class A, class Pred>
|
||||||
|
@ -10,6 +10,7 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <boost/unordered/detail/foa/flat_set_types.hpp>
|
||||||
#include <boost/unordered/detail/foa/table.hpp>
|
#include <boost/unordered/detail/foa/table.hpp>
|
||||||
#include <boost/unordered/detail/type_traits.hpp>
|
#include <boost/unordered/detail/type_traits.hpp>
|
||||||
#include <boost/unordered/unordered_flat_set_fwd.hpp>
|
#include <boost/unordered/unordered_flat_set_fwd.hpp>
|
||||||
@ -30,38 +31,10 @@ namespace boost {
|
|||||||
#pragma warning(disable : 4714) /* marked as __forceinline not inlined */
|
#pragma warning(disable : 4714) /* marked as __forceinline not inlined */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace detail {
|
|
||||||
template <class Key> struct flat_set_types
|
|
||||||
{
|
|
||||||
using key_type = Key;
|
|
||||||
using init_type = Key;
|
|
||||||
using value_type = Key;
|
|
||||||
|
|
||||||
static Key const& extract(value_type const& key) { return key; }
|
|
||||||
|
|
||||||
using element_type = value_type;
|
|
||||||
|
|
||||||
static Key& value_from(element_type& x) { return x; }
|
|
||||||
|
|
||||||
static element_type&& move(element_type& x) { return std::move(x); }
|
|
||||||
|
|
||||||
template <class A, class... Args>
|
|
||||||
static void construct(A& al, value_type* p, Args&&... args)
|
|
||||||
{
|
|
||||||
boost::allocator_construct(al, p, std::forward<Args>(args)...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class A> static void destroy(A& al, value_type* p) noexcept
|
|
||||||
{
|
|
||||||
boost::allocator_destroy(al, p);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} // namespace detail
|
|
||||||
|
|
||||||
template <class Key, class Hash, class KeyEqual, class Allocator>
|
template <class Key, class Hash, class KeyEqual, class Allocator>
|
||||||
class unordered_flat_set
|
class unordered_flat_set
|
||||||
{
|
{
|
||||||
using set_types = detail::flat_set_types<Key>;
|
using set_types = detail::foa::flat_set_types<Key>;
|
||||||
|
|
||||||
using table_type = detail::foa::table<set_types, Hash, KeyEqual,
|
using table_type = detail::foa::table<set_types, Hash, KeyEqual,
|
||||||
typename boost::allocator_rebind<Allocator,
|
typename boost::allocator_rebind<Allocator,
|
||||||
@ -70,8 +43,7 @@ namespace boost {
|
|||||||
table_type table_;
|
table_type table_;
|
||||||
|
|
||||||
template <class K, class H, class KE, class A>
|
template <class K, class H, class KE, class A>
|
||||||
bool friend operator==(
|
bool friend operator==(unordered_flat_set<K, H, KE, A> const& lhs,
|
||||||
unordered_flat_set<K, H, KE, A> const& lhs,
|
|
||||||
unordered_flat_set<K, H, KE, A> const& rhs);
|
unordered_flat_set<K, H, KE, A> const& rhs);
|
||||||
|
|
||||||
template <class K, class H, class KE, class A, class Pred>
|
template <class K, class H, class KE, class A, class Pred>
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
#include <boost/unordered/detail/foa/element_type.hpp>
|
#include <boost/unordered/detail/foa/element_type.hpp>
|
||||||
#include <boost/unordered/detail/foa/node_handle.hpp>
|
#include <boost/unordered/detail/foa/node_handle.hpp>
|
||||||
|
#include <boost/unordered/detail/foa/node_map_types.hpp>
|
||||||
#include <boost/unordered/detail/foa/table.hpp>
|
#include <boost/unordered/detail/foa/table.hpp>
|
||||||
#include <boost/unordered/detail/type_traits.hpp>
|
#include <boost/unordered/detail/type_traits.hpp>
|
||||||
#include <boost/unordered/unordered_node_map_fwd.hpp>
|
#include <boost/unordered/unordered_node_map_fwd.hpp>
|
||||||
@ -35,112 +36,6 @@ namespace boost {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template <class Key, class T> struct node_map_types
|
|
||||||
{
|
|
||||||
using key_type = Key;
|
|
||||||
using mapped_type = T;
|
|
||||||
using raw_key_type = typename std::remove_const<Key>::type;
|
|
||||||
using raw_mapped_type = typename std::remove_const<T>::type;
|
|
||||||
|
|
||||||
using init_type = std::pair<raw_key_type, raw_mapped_type>;
|
|
||||||
using value_type = std::pair<Key const, T>;
|
|
||||||
using moved_type = std::pair<raw_key_type&&, raw_mapped_type&&>;
|
|
||||||
|
|
||||||
using element_type=foa::element_type<value_type>;
|
|
||||||
|
|
||||||
static value_type& value_from(element_type const& x) { return *(x.p); }
|
|
||||||
|
|
||||||
template <class K, class V>
|
|
||||||
static raw_key_type const& extract(std::pair<K, V> const& kv)
|
|
||||||
{
|
|
||||||
return kv.first;
|
|
||||||
}
|
|
||||||
|
|
||||||
static raw_key_type const& extract(element_type const& kv)
|
|
||||||
{
|
|
||||||
return kv.p->first;
|
|
||||||
}
|
|
||||||
|
|
||||||
static element_type&& move(element_type& x) { return std::move(x); }
|
|
||||||
static moved_type move(init_type& x)
|
|
||||||
{
|
|
||||||
return {std::move(x.first), std::move(x.second)};
|
|
||||||
}
|
|
||||||
|
|
||||||
static moved_type move(value_type& x)
|
|
||||||
{
|
|
||||||
return {std::move(const_cast<raw_key_type&>(x.first)),
|
|
||||||
std::move(const_cast<raw_mapped_type&>(x.second))};
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class A>
|
|
||||||
static void construct(A&, element_type* p, element_type&& x) noexcept
|
|
||||||
{
|
|
||||||
p->p = x.p;
|
|
||||||
x.p = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class A>
|
|
||||||
static void construct(A& al, element_type* p, element_type const& copy)
|
|
||||||
{
|
|
||||||
construct(al, p, *copy.p);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class A, class... Args>
|
|
||||||
static void construct(A& al, init_type* p, 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)
|
|
||||||
{
|
|
||||||
boost::allocator_construct(al, p, std::forward<Args>(args)...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class A, class... Args>
|
|
||||||
static void construct(A& al, element_type* p, Args&&... args)
|
|
||||||
{
|
|
||||||
p->p = boost::to_address(boost::allocator_allocate(al, 1));
|
|
||||||
BOOST_TRY
|
|
||||||
{
|
|
||||||
boost::allocator_construct(al, p->p, std::forward<Args>(args)...);
|
|
||||||
}
|
|
||||||
BOOST_CATCH(...)
|
|
||||||
{
|
|
||||||
using pointer_type = typename boost::allocator_pointer<A>::type;
|
|
||||||
using pointer_traits = boost::pointer_traits<pointer_type>;
|
|
||||||
|
|
||||||
boost::allocator_deallocate(
|
|
||||||
al, pointer_traits::pointer_to(*(p->p)), 1);
|
|
||||||
BOOST_RETHROW
|
|
||||||
}
|
|
||||||
BOOST_CATCH_END
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class A> static void destroy(A& al, value_type* p) noexcept
|
|
||||||
{
|
|
||||||
boost::allocator_destroy(al, p);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class A> static void destroy(A& al, init_type* p) noexcept
|
|
||||||
{
|
|
||||||
boost::allocator_destroy(al, p);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class A> static void destroy(A& al, element_type* p) noexcept
|
|
||||||
{
|
|
||||||
if (p->p) {
|
|
||||||
using pointer_type = typename boost::allocator_pointer<A>::type;
|
|
||||||
using pointer_traits = boost::pointer_traits<pointer_type>;
|
|
||||||
|
|
||||||
destroy(al, p->p);
|
|
||||||
boost::allocator_deallocate(
|
|
||||||
al, pointer_traits::pointer_to(*(p->p)), 1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class TypePolicy, class Allocator>
|
template <class TypePolicy, class Allocator>
|
||||||
struct node_map_handle
|
struct node_map_handle
|
||||||
: public detail::foa::node_handle_base<TypePolicy, Allocator>
|
: public detail::foa::node_handle_base<TypePolicy, Allocator>
|
||||||
@ -179,7 +74,7 @@ namespace boost {
|
|||||||
template <class Key, class T, class Hash, class KeyEqual, class Allocator>
|
template <class Key, class T, class Hash, class KeyEqual, class Allocator>
|
||||||
class unordered_node_map
|
class unordered_node_map
|
||||||
{
|
{
|
||||||
using map_types = detail::node_map_types<Key, T>;
|
using map_types = detail::foa::node_map_types<Key, T>;
|
||||||
|
|
||||||
using table_type = detail::foa::table<map_types, Hash, KeyEqual,
|
using table_type = detail::foa::table<map_types, Hash, KeyEqual,
|
||||||
typename boost::allocator_rebind<Allocator,
|
typename boost::allocator_rebind<Allocator,
|
||||||
@ -188,8 +83,7 @@ namespace boost {
|
|||||||
table_type table_;
|
table_type table_;
|
||||||
|
|
||||||
template <class K, class V, class H, class KE, class A>
|
template <class K, class V, class H, class KE, class A>
|
||||||
bool friend operator==(
|
bool friend operator==(unordered_node_map<K, V, H, KE, A> const& lhs,
|
||||||
unordered_node_map<K, V, H, KE, A> const& lhs,
|
|
||||||
unordered_node_map<K, V, H, KE, A> const& rhs);
|
unordered_node_map<K, V, H, KE, A> const& rhs);
|
||||||
|
|
||||||
template <class K, class V, class H, class KE, class A, class Pred>
|
template <class K, class V, class H, class KE, class A, class Pred>
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
#include <boost/unordered/detail/foa/element_type.hpp>
|
#include <boost/unordered/detail/foa/element_type.hpp>
|
||||||
#include <boost/unordered/detail/foa/node_handle.hpp>
|
#include <boost/unordered/detail/foa/node_handle.hpp>
|
||||||
|
#include <boost/unordered/detail/foa/node_set_types.hpp>
|
||||||
#include <boost/unordered/detail/foa/table.hpp>
|
#include <boost/unordered/detail/foa/table.hpp>
|
||||||
#include <boost/unordered/detail/type_traits.hpp>
|
#include <boost/unordered/detail/type_traits.hpp>
|
||||||
#include <boost/unordered/unordered_node_set_fwd.hpp>
|
#include <boost/unordered/unordered_node_set_fwd.hpp>
|
||||||
@ -34,77 +35,6 @@ namespace boost {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace detail {
|
namespace detail {
|
||||||
template <class Key> struct node_set_types
|
|
||||||
{
|
|
||||||
using key_type = Key;
|
|
||||||
using init_type = Key;
|
|
||||||
using value_type = Key;
|
|
||||||
|
|
||||||
static Key const& extract(value_type const& key) { return key; }
|
|
||||||
|
|
||||||
using element_type=foa::element_type<value_type>;
|
|
||||||
|
|
||||||
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); }
|
|
||||||
static value_type&& move(value_type& x) { return std::move(x); }
|
|
||||||
|
|
||||||
template <class A>
|
|
||||||
static void construct(A& al, element_type* p, element_type const& copy)
|
|
||||||
{
|
|
||||||
construct(al, p, *copy.p);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename Allocator>
|
|
||||||
static void construct(
|
|
||||||
Allocator&, element_type* p, element_type&& x) noexcept
|
|
||||||
{
|
|
||||||
p->p = x.p;
|
|
||||||
x.p = nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class A, class... Args>
|
|
||||||
static void construct(A& al, value_type* p, Args&&... args)
|
|
||||||
{
|
|
||||||
boost::allocator_construct(al, p, std::forward<Args>(args)...);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class A, class... Args>
|
|
||||||
static void construct(A& al, element_type* p, Args&&... args)
|
|
||||||
{
|
|
||||||
p->p = boost::to_address(boost::allocator_allocate(al, 1));
|
|
||||||
BOOST_TRY
|
|
||||||
{
|
|
||||||
boost::allocator_construct(al, p->p, std::forward<Args>(args)...);
|
|
||||||
}
|
|
||||||
BOOST_CATCH(...)
|
|
||||||
{
|
|
||||||
boost::allocator_deallocate(al,
|
|
||||||
boost::pointer_traits<
|
|
||||||
typename boost::allocator_pointer<A>::type>::pointer_to(*p->p),
|
|
||||||
1);
|
|
||||||
BOOST_RETHROW
|
|
||||||
}
|
|
||||||
BOOST_CATCH_END
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class A> static void destroy(A& al, value_type* p) noexcept
|
|
||||||
{
|
|
||||||
boost::allocator_destroy(al, p);
|
|
||||||
}
|
|
||||||
|
|
||||||
template <class A> static void destroy(A& al, element_type* p) noexcept
|
|
||||||
{
|
|
||||||
if (p->p) {
|
|
||||||
destroy(al, p->p);
|
|
||||||
boost::allocator_deallocate(al,
|
|
||||||
boost::pointer_traits<typename boost::allocator_pointer<
|
|
||||||
A>::type>::pointer_to(*(p->p)),
|
|
||||||
1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
template <class TypePolicy, class Allocator>
|
template <class TypePolicy, class Allocator>
|
||||||
struct node_set_handle
|
struct node_set_handle
|
||||||
: public detail::foa::node_handle_base<TypePolicy, Allocator>
|
: public detail::foa::node_handle_base<TypePolicy, Allocator>
|
||||||
@ -135,7 +65,7 @@ namespace boost {
|
|||||||
template <class Key, class Hash, class KeyEqual, class Allocator>
|
template <class Key, class Hash, class KeyEqual, class Allocator>
|
||||||
class unordered_node_set
|
class unordered_node_set
|
||||||
{
|
{
|
||||||
using set_types = detail::node_set_types<Key>;
|
using set_types = detail::foa::node_set_types<Key>;
|
||||||
|
|
||||||
using table_type = detail::foa::table<set_types, Hash, KeyEqual,
|
using table_type = detail::foa::table<set_types, Hash, KeyEqual,
|
||||||
typename boost::allocator_rebind<Allocator,
|
typename boost::allocator_rebind<Allocator,
|
||||||
@ -144,8 +74,7 @@ namespace boost {
|
|||||||
table_type table_;
|
table_type table_;
|
||||||
|
|
||||||
template <class K, class H, class KE, class A>
|
template <class K, class H, class KE, class A>
|
||||||
bool friend operator==(
|
bool friend operator==(unordered_node_set<K, H, KE, A> const& lhs,
|
||||||
unordered_node_set<K, H, KE, A> const& lhs,
|
|
||||||
unordered_node_set<K, H, KE, A> const& rhs);
|
unordered_node_set<K, H, KE, A> const& rhs);
|
||||||
|
|
||||||
template <class K, class H, class KE, class A, class Pred>
|
template <class K, class H, class KE, class A, class Pred>
|
||||||
|
Reference in New Issue
Block a user