mirror of
https://github.com/boostorg/intrusive.git
synced 2025-08-03 06:24:44 +02:00
pack_options is now public, documented and tested so that it can be used by other libraries like Container, to specify new options for customizable containers.
This commit is contained in:
@@ -53,7 +53,9 @@ doxygen autodoc
|
|||||||
\"avltree_impl=avltree\" \\
|
\"avltree_impl=avltree\" \\
|
||||||
\"treap_set_impl=treap_set\" \\
|
\"treap_set_impl=treap_set\" \\
|
||||||
\"treap_multiset_impl=treap_multiset\" \\
|
\"treap_multiset_impl=treap_multiset\" \\
|
||||||
\"treap_impl=treap\""
|
\"treap_impl=treap\" \\
|
||||||
|
\"BOOST_INTRUSIVE_OPTION_CONSTANT(OPTION_NAME, TYPE, VALUE, CONSTANT_NAME) = template<TYPE VALUE> struct OPTION_NAME{};\" \\
|
||||||
|
\"BOOST_INTRUSIVE_OPTION_TYPE(OPTION_NAME, TYPE, TYPEDEF_EXPR, TYPEDEF_NAME) = template<class TYPE> struct OPTION_NAME{};\" "
|
||||||
;
|
;
|
||||||
|
|
||||||
xml intrusive : intrusive.qbk
|
xml intrusive : intrusive.qbk
|
||||||
|
@@ -24,7 +24,8 @@ class MyClass : public auto_unlink_hook
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
MyClass(int i = 0) : int_(i) {}
|
MyClass(int i = 0) : int_(i) {}
|
||||||
void unlink() { auto_unlink_hook::unlink(); }
|
int get_int() { return int_; }
|
||||||
|
void unlink() { auto_unlink_hook::unlink(); }
|
||||||
bool is_linked() { return auto_unlink_hook::is_linked(); }
|
bool is_linked() { return auto_unlink_hook::is_linked(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -16,15 +16,15 @@
|
|||||||
#include <boost/intrusive/detail/config_begin.hpp>
|
#include <boost/intrusive/detail/config_begin.hpp>
|
||||||
#include <boost/intrusive/intrusive_fwd.hpp>
|
#include <boost/intrusive/intrusive_fwd.hpp>
|
||||||
#include <boost/intrusive/link_mode.hpp>
|
#include <boost/intrusive/link_mode.hpp>
|
||||||
|
#include <boost/intrusive/pack_options.hpp>
|
||||||
#include <boost/intrusive/detail/mpl.hpp>
|
#include <boost/intrusive/detail/mpl.hpp>
|
||||||
#include <boost/intrusive/detail/utilities.hpp>
|
#include <boost/intrusive/detail/utilities.hpp>
|
||||||
#include <boost/static_assert.hpp>
|
#include <boost/static_assert.hpp>
|
||||||
|
|
||||||
|
|
||||||
namespace boost {
|
namespace boost {
|
||||||
namespace intrusive {
|
namespace intrusive {
|
||||||
|
|
||||||
/// @cond
|
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||||
|
|
||||||
//typedef void default_tag;
|
//typedef void default_tag;
|
||||||
struct default_tag;
|
struct default_tag;
|
||||||
@@ -34,8 +34,6 @@ namespace detail{
|
|||||||
|
|
||||||
struct default_hook_tag{};
|
struct default_hook_tag{};
|
||||||
|
|
||||||
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
|
||||||
|
|
||||||
#define BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER) \
|
#define BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER) \
|
||||||
struct BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER : public default_hook_tag\
|
struct BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER : public default_hook_tag\
|
||||||
{\
|
{\
|
||||||
@@ -50,14 +48,9 @@ BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_rbtree_hook);
|
|||||||
BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_hashtable_hook);
|
BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_hashtable_hook);
|
||||||
BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_avltree_hook);
|
BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_avltree_hook);
|
||||||
BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_bstree_hook);
|
BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_bstree_hook);
|
||||||
//BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_splaytree_hook);
|
|
||||||
//BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_sgtree_hook);
|
|
||||||
//BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION(default_treap_hook);
|
|
||||||
|
|
||||||
#undef BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION
|
#undef BOOST_INTRUSIVE_DEFAULT_HOOK_MARKER_DEFINITION
|
||||||
|
|
||||||
#endif //BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
|
||||||
|
|
||||||
template <class ValueTraits>
|
template <class ValueTraits>
|
||||||
struct eval_value_traits
|
struct eval_value_traits
|
||||||
{
|
{
|
||||||
@@ -165,7 +158,7 @@ struct get_value_traits
|
|||||||
//...get it's internal value traits using
|
//...get it's internal value traits using
|
||||||
//the provided T value type.
|
//the provided T value type.
|
||||||
, get_base_value_traits<T, supposed_value_traits>
|
, get_base_value_traits<T, supposed_value_traits>
|
||||||
//...else use it's internal value traits tag
|
//...else use its internal value traits tag
|
||||||
//(member hooks and custom value traits are in this group)
|
//(member hooks and custom value traits are in this group)
|
||||||
, detail::eval_if_c
|
, detail::eval_if_c
|
||||||
< internal_member_value_traits<supposed_value_traits>::value
|
< internal_member_value_traits<supposed_value_traits>::value
|
||||||
@@ -191,7 +184,7 @@ struct get_node_traits
|
|||||||
//...get it's internal value traits using
|
//...get it's internal value traits using
|
||||||
//the provided T value type.
|
//the provided T value type.
|
||||||
, get_base_node_traits<supposed_value_traits>
|
, get_base_node_traits<supposed_value_traits>
|
||||||
//...else use it's internal value traits tag
|
//...else use its internal value traits tag
|
||||||
//(member hooks and custom value traits are in this group)
|
//(member hooks and custom value traits are in this group)
|
||||||
, detail::eval_if_c
|
, detail::eval_if_c
|
||||||
< internal_member_value_traits<supposed_value_traits>::value
|
< internal_member_value_traits<supposed_value_traits>::value
|
||||||
@@ -203,50 +196,20 @@ struct get_node_traits
|
|||||||
|
|
||||||
} //namespace detail{
|
} //namespace detail{
|
||||||
|
|
||||||
/// @endcond
|
#endif //BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||||
|
|
||||||
//!This option setter specifies if the intrusive
|
//!This option setter specifies if the intrusive
|
||||||
//!container stores its size as a member to
|
//!container stores its size as a member to
|
||||||
//!obtain constant-time size() member.
|
//!obtain constant-time size() member.
|
||||||
template<bool Enabled>
|
BOOST_INTRUSIVE_OPTION_CONSTANT(constant_time_size, bool, Enabled, constant_time_size)
|
||||||
struct constant_time_size
|
|
||||||
{
|
|
||||||
/// @cond
|
|
||||||
template<class Base>
|
|
||||||
struct pack : Base
|
|
||||||
{
|
|
||||||
static const bool constant_time_size = Enabled;
|
|
||||||
};
|
|
||||||
/// @endcond
|
|
||||||
};
|
|
||||||
|
|
||||||
//!This option setter specifies the type that
|
//!This option setter specifies the type that
|
||||||
//!the container will use to store its size.
|
//!the container will use to store its size.
|
||||||
template<class SizeType>
|
BOOST_INTRUSIVE_OPTION_TYPE(size_type, SizeType, SizeType, size_type)
|
||||||
struct size_type
|
|
||||||
{
|
|
||||||
/// @cond
|
|
||||||
template<class Base>
|
|
||||||
struct pack : Base
|
|
||||||
{
|
|
||||||
typedef SizeType size_type;
|
|
||||||
};
|
|
||||||
/// @endcond
|
|
||||||
};
|
|
||||||
|
|
||||||
//!This option setter specifies the strict weak ordering
|
//!This option setter specifies the strict weak ordering
|
||||||
//!comparison functor for the value type
|
//!comparison functor for the value type
|
||||||
template<class Compare>
|
BOOST_INTRUSIVE_OPTION_TYPE(compare, Compare, Compare, compare)
|
||||||
struct compare
|
|
||||||
{
|
|
||||||
/// @cond
|
|
||||||
template<class Base>
|
|
||||||
struct pack : Base
|
|
||||||
{
|
|
||||||
typedef Compare compare;
|
|
||||||
};
|
|
||||||
/// @endcond
|
|
||||||
};
|
|
||||||
|
|
||||||
//!This option setter for scapegoat containers specifies if
|
//!This option setter for scapegoat containers specifies if
|
||||||
//!the intrusive scapegoat container should use a non-variable
|
//!the intrusive scapegoat container should use a non-variable
|
||||||
@@ -260,74 +223,39 @@ struct compare
|
|||||||
//!If the user only needs an alpha value near 1/sqrt(2), this
|
//!If the user only needs an alpha value near 1/sqrt(2), this
|
||||||
//!option also improves performance since avoids logarithm
|
//!option also improves performance since avoids logarithm
|
||||||
//!and division operations when rebalancing the tree.
|
//!and division operations when rebalancing the tree.
|
||||||
template<bool Enabled>
|
BOOST_INTRUSIVE_OPTION_CONSTANT(floating_point, bool, Enabled, floating_point)
|
||||||
struct floating_point
|
|
||||||
{
|
|
||||||
/// @cond
|
|
||||||
template<class Base>
|
|
||||||
struct pack : Base
|
|
||||||
{
|
|
||||||
static const bool floating_point = Enabled;
|
|
||||||
};
|
|
||||||
/// @endcond
|
|
||||||
};
|
|
||||||
|
|
||||||
//!This option setter specifies the equality
|
//!This option setter specifies the equality
|
||||||
//!functor for the value type
|
//!functor for the value type
|
||||||
template<class Equal>
|
BOOST_INTRUSIVE_OPTION_TYPE(equal, Equal, Equal, equal)
|
||||||
struct equal
|
|
||||||
{
|
|
||||||
/// @cond
|
|
||||||
template<class Base>
|
|
||||||
struct pack : Base
|
|
||||||
{
|
|
||||||
typedef Equal equal;
|
|
||||||
};
|
|
||||||
/// @endcond
|
|
||||||
};
|
|
||||||
|
|
||||||
//!This option setter specifies the equality
|
//!This option setter specifies the equality
|
||||||
//!functor for the value type
|
//!functor for the value type
|
||||||
template<class Priority>
|
BOOST_INTRUSIVE_OPTION_TYPE(priority, Priority, Priority, priority)
|
||||||
struct priority
|
|
||||||
{
|
|
||||||
/// @cond
|
|
||||||
template<class Base>
|
|
||||||
struct pack : Base
|
|
||||||
{
|
|
||||||
typedef Priority priority;
|
|
||||||
};
|
|
||||||
/// @endcond
|
|
||||||
};
|
|
||||||
|
|
||||||
//!This option setter specifies the hash
|
//!This option setter specifies the hash
|
||||||
//!functor for the value type
|
//!functor for the value type
|
||||||
template<class Hash>
|
BOOST_INTRUSIVE_OPTION_TYPE(hash, Hash, Hash, hash)
|
||||||
struct hash
|
|
||||||
{
|
|
||||||
/// @cond
|
|
||||||
template<class Base>
|
|
||||||
struct pack : Base
|
|
||||||
{
|
|
||||||
typedef Hash hash;
|
|
||||||
};
|
|
||||||
/// @endcond
|
|
||||||
};
|
|
||||||
|
|
||||||
//!This option setter specifies the relationship between the type
|
//!This option setter specifies the relationship between the type
|
||||||
//!to be managed by the container (the value type) and the node to be
|
//!to be managed by the container (the value type) and the node to be
|
||||||
//!used in the node algorithms. It also specifies the linking policy.
|
//!used in the node algorithms. It also specifies the linking policy.
|
||||||
template<typename ValueTraits>
|
BOOST_INTRUSIVE_OPTION_TYPE(value_traits, ValueTraits, ValueTraits, proto_value_traits)
|
||||||
struct value_traits
|
|
||||||
{
|
//#define BOOST_INTRUSIVE_COMMA ,
|
||||||
/// @cond
|
//#define BOOST_INTRUSIVE_LESS <
|
||||||
template<class Base>
|
//#define BOOST_INTRUSIVE_MORE >
|
||||||
struct pack : Base
|
//BOOST_INTRUSIVE_OPTION_TYPE (member_hook, Parent BOOST_INTRUSIVE_COMMA class MemberHook BOOST_INTRUSIVE_COMMA MemberHook Parent::* PtrToMember , mhtraits BOOST_INTRUSIVE_LESS Parent BOOST_INTRUSIVE_COMMA MemberHook BOOST_INTRUSIVE_COMMA PtrToMember BOOST_INTRUSIVE_MORE , proto_value_traits)
|
||||||
{
|
//template< class Parent , class MemberHook , MemberHook Parent::* PtrToMember>
|
||||||
typedef ValueTraits proto_value_traits;
|
//struct member_hook {
|
||||||
};
|
// template<class Base> struct pack : Base {
|
||||||
/// @endcond
|
// typedef mhtraits < Parent , MemberHook , PtrToMember > proto_value_traits;
|
||||||
};
|
// };
|
||||||
|
//};
|
||||||
|
//
|
||||||
|
//#undef BOOST_INTRUSIVE_COMMA
|
||||||
|
//#undef BOOST_INTRUSIVE_LESS
|
||||||
|
//#undef BOOST_INTRUSIVE_MORE
|
||||||
|
|
||||||
//!This option setter specifies the member hook the
|
//!This option setter specifies the member hook the
|
||||||
//!container must use.
|
//!container must use.
|
||||||
@@ -336,27 +264,21 @@ template< typename Parent
|
|||||||
, MemberHook Parent::* PtrToMember>
|
, MemberHook Parent::* PtrToMember>
|
||||||
struct member_hook
|
struct member_hook
|
||||||
{
|
{
|
||||||
/// @cond
|
// @cond
|
||||||
/*
|
// typedef typename MemberHook::hooktags::node_traits node_traits;
|
||||||
typedef typename MemberHook::hooktags::node_traits node_traits;
|
// typedef typename node_traits::node node_type;
|
||||||
typedef typename node_traits::node node_type;
|
// typedef node_type Parent::* Ptr2MemNode;
|
||||||
typedef node_type Parent::* Ptr2MemNode;
|
// typedef mhtraits
|
||||||
typedef mhtraits
|
// < Parent
|
||||||
< Parent
|
// , node_traits
|
||||||
, node_traits
|
// //This cast is really ugly but necessary to reduce template bloat.
|
||||||
//This cast is really ugly but necessary to reduce template bloat.
|
// //Since we control the layout between the hook and the node, and there is
|
||||||
//Since we control the layout between the hook and the node, and there is
|
// //always single inheritance, the offset of the node is exactly the offset of
|
||||||
//always single inheritance, the offset of the node is exactly the offset of
|
// //the hook. Since the node type is shared between all member hooks, this saves
|
||||||
//the hook. Since the node type is shared between all member hooks, this saves
|
// //quite a lot of symbol stuff.
|
||||||
//quite a lot of symbol stuff.
|
// , (Ptr2MemNode)PtrToMember
|
||||||
, (Ptr2MemNode)PtrToMember
|
// , MemberHook::hooktags::link_mode> member_value_traits;
|
||||||
, MemberHook::hooktags::link_mode> member_value_traits;
|
typedef mhtraits <Parent, MemberHook, PtrToMember> member_value_traits;
|
||||||
*/
|
|
||||||
typedef mhtraits
|
|
||||||
< Parent
|
|
||||||
, MemberHook
|
|
||||||
, PtrToMember
|
|
||||||
> member_value_traits;
|
|
||||||
template<class Base>
|
template<class Base>
|
||||||
struct pack : Base
|
struct pack : Base
|
||||||
{
|
{
|
||||||
@@ -365,158 +287,54 @@ struct member_hook
|
|||||||
/// @endcond
|
/// @endcond
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
//!This option setter specifies the function object that will
|
//!This option setter specifies the function object that will
|
||||||
//!be used to convert between values to be inserted in a container
|
//!be used to convert between values to be inserted in a container
|
||||||
//!and the hook to be used for that purpose.
|
//!and the hook to be used for that purpose.
|
||||||
template< typename Functor>
|
BOOST_INTRUSIVE_OPTION_TYPE(function_hook, Functor, fhtraits<Functor>, proto_value_traits)
|
||||||
struct function_hook
|
|
||||||
{
|
|
||||||
/// @cond
|
|
||||||
typedef fhtraits
|
|
||||||
<Functor> function_value_traits;
|
|
||||||
template<class Base>
|
|
||||||
struct pack : Base
|
|
||||||
{
|
|
||||||
typedef function_value_traits proto_value_traits;
|
|
||||||
};
|
|
||||||
/// @endcond
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//!This option setter specifies that the container
|
//!This option setter specifies that the container
|
||||||
//!must use the specified base hook
|
//!must use the specified base hook
|
||||||
template<typename BaseHook>
|
BOOST_INTRUSIVE_OPTION_TYPE(base_hook, BaseHook, BaseHook, proto_value_traits)
|
||||||
struct base_hook
|
|
||||||
{
|
|
||||||
/// @cond
|
|
||||||
template<class Base>
|
|
||||||
struct pack : Base
|
|
||||||
{
|
|
||||||
typedef BaseHook proto_value_traits;
|
|
||||||
};
|
|
||||||
/// @endcond
|
|
||||||
};
|
|
||||||
|
|
||||||
//!This option setter specifies the type of
|
//!This option setter specifies the type of
|
||||||
//!a void pointer. This will instruct the hook
|
//!a void pointer. This will instruct the hook
|
||||||
//!to use this type of pointer instead of the
|
//!to use this type of pointer instead of the
|
||||||
//!default one
|
//!default one
|
||||||
template<class VoidPointer>
|
BOOST_INTRUSIVE_OPTION_TYPE(void_pointer, VoidPointer, VoidPointer, void_pointer)
|
||||||
struct void_pointer
|
|
||||||
{
|
|
||||||
/// @cond
|
|
||||||
template<class Base>
|
|
||||||
struct pack : Base
|
|
||||||
{
|
|
||||||
typedef VoidPointer void_pointer;
|
|
||||||
};
|
|
||||||
/// @endcond
|
|
||||||
};
|
|
||||||
|
|
||||||
//!This option setter specifies the type of
|
//!This option setter specifies the type of
|
||||||
//!the tag of a base hook. A type cannot have two
|
//!the tag of a base hook. A type cannot have two
|
||||||
//!base hooks of the same type, so a tag can be used
|
//!base hooks of the same type, so a tag can be used
|
||||||
//!to differentiate two base hooks with otherwise same type
|
//!to differentiate two base hooks with otherwise same type
|
||||||
template<class Tag>
|
BOOST_INTRUSIVE_OPTION_TYPE(tag, Tag, Tag, tag)
|
||||||
struct tag
|
|
||||||
{
|
|
||||||
/// @cond
|
|
||||||
template<class Base>
|
|
||||||
struct pack : Base
|
|
||||||
{
|
|
||||||
typedef Tag tag;
|
|
||||||
};
|
|
||||||
/// @endcond
|
|
||||||
};
|
|
||||||
|
|
||||||
//!This option setter specifies the link mode
|
//!This option setter specifies the link mode
|
||||||
//!(normal_link, safe_link or auto_unlink)
|
//!(normal_link, safe_link or auto_unlink)
|
||||||
template<link_mode_type LinkType>
|
BOOST_INTRUSIVE_OPTION_CONSTANT(link_mode, link_mode_type, LinkType, link_mode)
|
||||||
struct link_mode
|
|
||||||
{
|
|
||||||
/// @cond
|
|
||||||
template<class Base>
|
|
||||||
struct pack : Base
|
|
||||||
{
|
|
||||||
static const link_mode_type link_mode = LinkType;
|
|
||||||
};
|
|
||||||
/// @endcond
|
|
||||||
};
|
|
||||||
|
|
||||||
//!This option setter specifies if the hook
|
//!This option setter specifies if the hook
|
||||||
//!should be optimized for size instead of for speed.
|
//!should be optimized for size instead of for speed.
|
||||||
template<bool Enabled>
|
BOOST_INTRUSIVE_OPTION_CONSTANT(optimize_size, bool, Enabled, optimize_size)
|
||||||
struct optimize_size
|
|
||||||
{
|
|
||||||
/// @cond
|
|
||||||
template<class Base>
|
|
||||||
struct pack : Base
|
|
||||||
{
|
|
||||||
static const bool optimize_size = Enabled;
|
|
||||||
};
|
|
||||||
/// @endcond
|
|
||||||
};
|
|
||||||
|
|
||||||
//!This option setter specifies if the list container should
|
//!This option setter specifies if the list container should
|
||||||
//!use a linear implementation instead of a circular one.
|
//!use a linear implementation instead of a circular one.
|
||||||
template<bool Enabled>
|
BOOST_INTRUSIVE_OPTION_CONSTANT(linear, bool, Enabled, linear)
|
||||||
struct linear
|
|
||||||
{
|
|
||||||
/// @cond
|
|
||||||
template<class Base>
|
|
||||||
struct pack : Base
|
|
||||||
{
|
|
||||||
static const bool linear = Enabled;
|
|
||||||
};
|
|
||||||
/// @endcond
|
|
||||||
};
|
|
||||||
|
|
||||||
//!This option setter specifies if the list container should
|
//!This option setter specifies if the list container should
|
||||||
//!use a linear implementation instead of a circular one.
|
//!use a linear implementation instead of a circular one.
|
||||||
template<bool Enabled>
|
BOOST_INTRUSIVE_OPTION_CONSTANT(cache_last, bool, Enabled, cache_last)
|
||||||
struct cache_last
|
|
||||||
{
|
|
||||||
/// @cond
|
|
||||||
template<class Base>
|
|
||||||
struct pack : Base
|
|
||||||
{
|
|
||||||
static const bool cache_last = Enabled;
|
|
||||||
};
|
|
||||||
/// @endcond
|
|
||||||
};
|
|
||||||
|
|
||||||
//!This option setter specifies the bucket traits
|
//!This option setter specifies the bucket traits
|
||||||
//!class for unordered associative containers. When this option is specified,
|
//!class for unordered associative containers. When this option is specified,
|
||||||
//!instead of using the default bucket traits, a user defined holder will be defined
|
//!instead of using the default bucket traits, a user defined holder will be defined
|
||||||
template<class BucketTraits>
|
BOOST_INTRUSIVE_OPTION_TYPE(bucket_traits, BucketTraits, BucketTraits, bucket_traits)
|
||||||
struct bucket_traits
|
|
||||||
{
|
|
||||||
/// @cond
|
|
||||||
template<class Base>
|
|
||||||
struct pack : Base
|
|
||||||
{
|
|
||||||
typedef BucketTraits bucket_traits;
|
|
||||||
};
|
|
||||||
/// @endcond
|
|
||||||
};
|
|
||||||
|
|
||||||
//!This option setter specifies if the unordered hook
|
//!This option setter specifies if the unordered hook
|
||||||
//!should offer room to store the hash value.
|
//!should offer room to store the hash value.
|
||||||
//!Storing the hash in the hook will speed up rehashing
|
//!Storing the hash in the hook will speed up rehashing
|
||||||
//!processes in applications where rehashing is frequent,
|
//!processes in applications where rehashing is frequent,
|
||||||
//!rehashing might throw or the value is heavy to hash.
|
//!rehashing might throw or the value is heavy to hash.
|
||||||
template<bool Enabled>
|
BOOST_INTRUSIVE_OPTION_CONSTANT(store_hash, bool, Enabled, store_hash)
|
||||||
struct store_hash
|
|
||||||
{
|
|
||||||
/// @cond
|
|
||||||
template<class Base>
|
|
||||||
struct pack : Base
|
|
||||||
{
|
|
||||||
static const bool store_hash = Enabled;
|
|
||||||
};
|
|
||||||
/// @endcond
|
|
||||||
};
|
|
||||||
|
|
||||||
//!This option setter specifies if the unordered hook
|
//!This option setter specifies if the unordered hook
|
||||||
//!should offer room to store another link to another node
|
//!should offer room to store another link to another node
|
||||||
@@ -524,51 +342,20 @@ struct store_hash
|
|||||||
//!Storing this link will speed up lookups and insertions on
|
//!Storing this link will speed up lookups and insertions on
|
||||||
//!unordered_multiset containers with a great number of elements
|
//!unordered_multiset containers with a great number of elements
|
||||||
//!with the same key.
|
//!with the same key.
|
||||||
template<bool Enabled>
|
BOOST_INTRUSIVE_OPTION_CONSTANT(optimize_multikey, bool, Enabled, optimize_multikey)
|
||||||
struct optimize_multikey
|
|
||||||
{
|
|
||||||
/// @cond
|
|
||||||
template<class Base>
|
|
||||||
struct pack : Base
|
|
||||||
{
|
|
||||||
static const bool optimize_multikey = Enabled;
|
|
||||||
};
|
|
||||||
/// @endcond
|
|
||||||
};
|
|
||||||
|
|
||||||
//!This option setter specifies if the bucket array will be always power of two.
|
//!This option setter specifies if the bucket array will be always power of two.
|
||||||
//!This allows using masks instead of the default modulo operation to determine
|
//!This allows using masks instead of the default modulo operation to determine
|
||||||
//!the bucket number from the hash value, leading to better performance.
|
//!the bucket number from the hash value, leading to better performance.
|
||||||
//!In debug mode, if power of two buckets mode is activated, the bucket length
|
//!In debug mode, if power of two buckets mode is activated, the bucket length
|
||||||
//!will be checked to through assertions to assure the bucket length is power of two.
|
//!will be checked to through assertions to assure the bucket length is power of two.
|
||||||
template<bool Enabled>
|
BOOST_INTRUSIVE_OPTION_CONSTANT(power_2_buckets, bool, Enabled, power_2_buckets)
|
||||||
struct power_2_buckets
|
|
||||||
{
|
|
||||||
/// @cond
|
|
||||||
template<class Base>
|
|
||||||
struct pack : Base
|
|
||||||
{
|
|
||||||
static const bool power_2_buckets = Enabled;
|
|
||||||
};
|
|
||||||
/// @endcond
|
|
||||||
};
|
|
||||||
|
|
||||||
//!This option setter specifies if the container will cache a pointer to the first
|
//!This option setter specifies if the container will cache a pointer to the first
|
||||||
//!non-empty bucket so that begin() is always constant-time.
|
//!non-empty bucket so that begin() is always constant-time.
|
||||||
//!This is specially helpful when we can have containers with a few elements
|
//!This is specially helpful when we can have containers with a few elements
|
||||||
//!but with big bucket arrays (that is, hashtables with low load factors).
|
//!but with big bucket arrays (that is, hashtables with low load factors).
|
||||||
template<bool Enabled>
|
BOOST_INTRUSIVE_OPTION_CONSTANT(cache_begin, bool, Enabled, cache_begin)
|
||||||
struct cache_begin
|
|
||||||
{
|
|
||||||
/// @cond
|
|
||||||
template<class Base>
|
|
||||||
struct pack : Base
|
|
||||||
{
|
|
||||||
static const bool cache_begin = Enabled;
|
|
||||||
};
|
|
||||||
/// @endcond
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
//!This option setter specifies if the container will compare the hash value
|
//!This option setter specifies if the container will compare the hash value
|
||||||
//!before comparing objects. This option can't be specified if store_hash<>
|
//!before comparing objects. This option can't be specified if store_hash<>
|
||||||
@@ -576,17 +363,7 @@ struct cache_begin
|
|||||||
//!This is specially helpful when we have containers with a high load factor.
|
//!This is specially helpful when we have containers with a high load factor.
|
||||||
//!and the comparison function is much more expensive that comparing already
|
//!and the comparison function is much more expensive that comparing already
|
||||||
//!stored hash values.
|
//!stored hash values.
|
||||||
template<bool Enabled>
|
BOOST_INTRUSIVE_OPTION_CONSTANT(compare_hash, bool, Enabled, compare_hash)
|
||||||
struct compare_hash
|
|
||||||
{
|
|
||||||
/// @cond
|
|
||||||
template<class Base>
|
|
||||||
struct pack : Base
|
|
||||||
{
|
|
||||||
static const bool compare_hash = Enabled;
|
|
||||||
};
|
|
||||||
/// @endcond
|
|
||||||
};
|
|
||||||
|
|
||||||
//!This option setter specifies if the hash container will use incremental
|
//!This option setter specifies if the hash container will use incremental
|
||||||
//!hashing. With incremental hashing the cost of hash table expansion is spread
|
//!hashing. With incremental hashing the cost of hash table expansion is spread
|
||||||
@@ -594,17 +371,7 @@ struct compare_hash
|
|||||||
//!Therefore linear hashing is well suited for interactive applications or real-time
|
//!Therefore linear hashing is well suited for interactive applications or real-time
|
||||||
//!appplications where the worst-case insertion time of non-incremental hash containers
|
//!appplications where the worst-case insertion time of non-incremental hash containers
|
||||||
//!(rehashing the whole bucket array) is not admisible.
|
//!(rehashing the whole bucket array) is not admisible.
|
||||||
template<bool Enabled>
|
BOOST_INTRUSIVE_OPTION_CONSTANT(incremental, bool, Enabled, incremental)
|
||||||
struct incremental
|
|
||||||
{
|
|
||||||
/// @cond
|
|
||||||
template<class Base>
|
|
||||||
struct pack : Base
|
|
||||||
{
|
|
||||||
static const bool incremental = Enabled;
|
|
||||||
};
|
|
||||||
/// @endcond
|
|
||||||
};
|
|
||||||
|
|
||||||
/// @cond
|
/// @cond
|
||||||
|
|
||||||
@@ -615,210 +382,6 @@ struct none
|
|||||||
{};
|
{};
|
||||||
};
|
};
|
||||||
|
|
||||||
//To-do: pass to variadic templates
|
|
||||||
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
|
||||||
|
|
||||||
template<class Prev, class Next>
|
|
||||||
struct do_pack
|
|
||||||
{
|
|
||||||
//Use "pack" member template to pack options
|
|
||||||
typedef typename Next::template pack<Prev> type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class Prev>
|
|
||||||
struct do_pack<Prev, void>
|
|
||||||
{
|
|
||||||
//Avoid packing "void" to shorten template names
|
|
||||||
typedef Prev type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template
|
|
||||||
< class DefaultOptions
|
|
||||||
, class O1 = void
|
|
||||||
, class O2 = void
|
|
||||||
, class O3 = void
|
|
||||||
, class O4 = void
|
|
||||||
, class O5 = void
|
|
||||||
, class O6 = void
|
|
||||||
, class O7 = void
|
|
||||||
, class O8 = void
|
|
||||||
, class O9 = void
|
|
||||||
, class O10 = void
|
|
||||||
, class O11 = void
|
|
||||||
>
|
|
||||||
struct pack_options
|
|
||||||
{
|
|
||||||
// join options
|
|
||||||
typedef
|
|
||||||
typename do_pack
|
|
||||||
< typename do_pack
|
|
||||||
< typename do_pack
|
|
||||||
< typename do_pack
|
|
||||||
< typename do_pack
|
|
||||||
< typename do_pack
|
|
||||||
< typename do_pack
|
|
||||||
< typename do_pack
|
|
||||||
< typename do_pack
|
|
||||||
< typename do_pack
|
|
||||||
< typename do_pack
|
|
||||||
< DefaultOptions
|
|
||||||
, O1
|
|
||||||
>::type
|
|
||||||
, O2
|
|
||||||
>::type
|
|
||||||
, O3
|
|
||||||
>::type
|
|
||||||
, O4
|
|
||||||
>::type
|
|
||||||
, O5
|
|
||||||
>::type
|
|
||||||
, O6
|
|
||||||
>::type
|
|
||||||
, O7
|
|
||||||
>::type
|
|
||||||
, O8
|
|
||||||
>::type
|
|
||||||
, O9
|
|
||||||
>::type
|
|
||||||
, O10
|
|
||||||
>::type
|
|
||||||
, O11
|
|
||||||
>::type
|
|
||||||
type;
|
|
||||||
};
|
|
||||||
#else
|
|
||||||
|
|
||||||
//index_tuple
|
|
||||||
template<int... Indexes>
|
|
||||||
struct index_tuple{};
|
|
||||||
|
|
||||||
//build_number_seq
|
|
||||||
template<std::size_t Num, typename Tuple = index_tuple<> >
|
|
||||||
struct build_number_seq;
|
|
||||||
|
|
||||||
template<std::size_t Num, int... Indexes>
|
|
||||||
struct build_number_seq<Num, index_tuple<Indexes...> >
|
|
||||||
: build_number_seq<Num - 1, index_tuple<Indexes..., sizeof...(Indexes)> >
|
|
||||||
{};
|
|
||||||
|
|
||||||
template<int... Indexes>
|
|
||||||
struct build_number_seq<0, index_tuple<Indexes...> >
|
|
||||||
{ typedef index_tuple<Indexes...> type; };
|
|
||||||
|
|
||||||
template<class ...Types>
|
|
||||||
struct typelist
|
|
||||||
{};
|
|
||||||
|
|
||||||
//invert_typelist
|
|
||||||
template<class T>
|
|
||||||
struct invert_typelist;
|
|
||||||
|
|
||||||
template<int I, typename Tuple>
|
|
||||||
struct typelist_element;
|
|
||||||
|
|
||||||
template<int I, typename Head, typename... Tail>
|
|
||||||
struct typelist_element<I, typelist<Head, Tail...> >
|
|
||||||
{
|
|
||||||
typedef typename typelist_element<I-1, typelist<Tail...> >::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<typename Head, typename... Tail>
|
|
||||||
struct typelist_element<0, typelist<Head, Tail...> >
|
|
||||||
{
|
|
||||||
typedef Head type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<int ...Ints, class ...Types>
|
|
||||||
typelist<typename typelist_element<(sizeof...(Types) - 1) - Ints, typelist<Types...> >::type...>
|
|
||||||
inverted_typelist(index_tuple<Ints...>, typelist<Types...>)
|
|
||||||
{
|
|
||||||
return typelist<typename typelist_element<(sizeof...(Types) - 1) - Ints, typelist<Types...> >::type...>();
|
|
||||||
}
|
|
||||||
|
|
||||||
//sizeof_typelist
|
|
||||||
template<class Typelist>
|
|
||||||
struct sizeof_typelist;
|
|
||||||
|
|
||||||
template<class ...Types>
|
|
||||||
struct sizeof_typelist< typelist<Types...> >
|
|
||||||
{
|
|
||||||
static const std::size_t value = sizeof...(Types);
|
|
||||||
};
|
|
||||||
|
|
||||||
//invert_typelist_impl
|
|
||||||
template<class Typelist, class Indexes>
|
|
||||||
struct invert_typelist_impl;
|
|
||||||
|
|
||||||
|
|
||||||
template<class Typelist, int ...Ints>
|
|
||||||
struct invert_typelist_impl< Typelist, index_tuple<Ints...> >
|
|
||||||
{
|
|
||||||
static const std::size_t last_idx = sizeof_typelist<Typelist>::value - 1;
|
|
||||||
typedef typelist
|
|
||||||
<typename typelist_element<last_idx - Ints, Typelist>::type...> type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class Typelist, int Int>
|
|
||||||
struct invert_typelist_impl< Typelist, index_tuple<Int> >
|
|
||||||
{
|
|
||||||
typedef Typelist type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class Typelist>
|
|
||||||
struct invert_typelist_impl< Typelist, index_tuple<> >
|
|
||||||
{
|
|
||||||
typedef Typelist type;
|
|
||||||
};
|
|
||||||
|
|
||||||
//invert_typelist
|
|
||||||
template<class Typelist>
|
|
||||||
struct invert_typelist;
|
|
||||||
|
|
||||||
template<class ...Types>
|
|
||||||
struct invert_typelist< typelist<Types...> >
|
|
||||||
{
|
|
||||||
typedef typelist<Types...> typelist_t;
|
|
||||||
typedef typename build_number_seq<sizeof...(Types)>::type indexes_t;
|
|
||||||
typedef typename invert_typelist_impl<typelist_t, indexes_t>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
//Do pack
|
|
||||||
template<class Typelist>
|
|
||||||
struct do_pack;
|
|
||||||
|
|
||||||
template<>
|
|
||||||
struct do_pack<typelist<> >;
|
|
||||||
|
|
||||||
template<class Prev>
|
|
||||||
struct do_pack<typelist<Prev> >
|
|
||||||
{
|
|
||||||
typedef Prev type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class Prev, class Last>
|
|
||||||
struct do_pack<typelist<Prev, Last> >
|
|
||||||
{
|
|
||||||
typedef typename Prev::template pack<Last> type;
|
|
||||||
};
|
|
||||||
|
|
||||||
template<class Prev, class ...Others>
|
|
||||||
struct do_pack<typelist<Prev, Others...> >
|
|
||||||
{
|
|
||||||
typedef typename Prev::template pack
|
|
||||||
<typename do_pack<typelist<Others...> >::type> type;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
template<class ...Options>
|
|
||||||
struct pack_options
|
|
||||||
{
|
|
||||||
typedef typelist<Options...> typelist_t;
|
|
||||||
typedef typename invert_typelist<typelist_t>::type inverted_typelist;
|
|
||||||
typedef typename do_pack<inverted_typelist>::type type;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct hook_defaults
|
struct hook_defaults
|
||||||
{
|
{
|
||||||
typedef void* void_pointer;
|
typedef void* void_pointer;
|
||||||
|
370
include/boost/intrusive/pack_options.hpp
Normal file
370
include/boost/intrusive/pack_options.hpp
Normal file
@@ -0,0 +1,370 @@
|
|||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// (C) Copyright Ion Gaztanaga 2013-2013
|
||||||
|
//
|
||||||
|
// 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)
|
||||||
|
//
|
||||||
|
// See http://www.boost.org/libs/intrusive for documentation.
|
||||||
|
//
|
||||||
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef BOOST_INTRUSIVE_PACK_OPTIONS_HPP
|
||||||
|
#define BOOST_INTRUSIVE_PACK_OPTIONS_HPP
|
||||||
|
|
||||||
|
#include <boost/intrusive/detail/config_begin.hpp>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
namespace intrusive {
|
||||||
|
|
||||||
|
#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||||
|
|
||||||
|
#if !defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||||
|
|
||||||
|
template<class Prev, class Next>
|
||||||
|
struct do_pack
|
||||||
|
{
|
||||||
|
//Use "pack" member template to pack options
|
||||||
|
typedef typename Next::template pack<Prev> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class Prev>
|
||||||
|
struct do_pack<Prev, void>
|
||||||
|
{
|
||||||
|
//Avoid packing "void" to shorten template names
|
||||||
|
typedef Prev type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template
|
||||||
|
< class DefaultOptions
|
||||||
|
, class O1 = void
|
||||||
|
, class O2 = void
|
||||||
|
, class O3 = void
|
||||||
|
, class O4 = void
|
||||||
|
, class O5 = void
|
||||||
|
, class O6 = void
|
||||||
|
, class O7 = void
|
||||||
|
, class O8 = void
|
||||||
|
, class O9 = void
|
||||||
|
, class O10 = void
|
||||||
|
, class O11 = void
|
||||||
|
>
|
||||||
|
struct pack_options
|
||||||
|
{
|
||||||
|
// join options
|
||||||
|
typedef
|
||||||
|
typename do_pack
|
||||||
|
< typename do_pack
|
||||||
|
< typename do_pack
|
||||||
|
< typename do_pack
|
||||||
|
< typename do_pack
|
||||||
|
< typename do_pack
|
||||||
|
< typename do_pack
|
||||||
|
< typename do_pack
|
||||||
|
< typename do_pack
|
||||||
|
< typename do_pack
|
||||||
|
< typename do_pack
|
||||||
|
< DefaultOptions
|
||||||
|
, O1
|
||||||
|
>::type
|
||||||
|
, O2
|
||||||
|
>::type
|
||||||
|
, O3
|
||||||
|
>::type
|
||||||
|
, O4
|
||||||
|
>::type
|
||||||
|
, O5
|
||||||
|
>::type
|
||||||
|
, O6
|
||||||
|
>::type
|
||||||
|
, O7
|
||||||
|
>::type
|
||||||
|
, O8
|
||||||
|
>::type
|
||||||
|
, O9
|
||||||
|
>::type
|
||||||
|
, O10
|
||||||
|
>::type
|
||||||
|
, O11
|
||||||
|
>::type
|
||||||
|
type;
|
||||||
|
};
|
||||||
|
#else
|
||||||
|
|
||||||
|
//index_tuple
|
||||||
|
template<int... Indexes>
|
||||||
|
struct index_tuple{};
|
||||||
|
|
||||||
|
//build_number_seq
|
||||||
|
template<std::size_t Num, typename Tuple = index_tuple<> >
|
||||||
|
struct build_number_seq;
|
||||||
|
|
||||||
|
template<std::size_t Num, int... Indexes>
|
||||||
|
struct build_number_seq<Num, index_tuple<Indexes...> >
|
||||||
|
: build_number_seq<Num - 1, index_tuple<Indexes..., sizeof...(Indexes)> >
|
||||||
|
{};
|
||||||
|
|
||||||
|
template<int... Indexes>
|
||||||
|
struct build_number_seq<0, index_tuple<Indexes...> >
|
||||||
|
{ typedef index_tuple<Indexes...> type; };
|
||||||
|
|
||||||
|
template<class ...Types>
|
||||||
|
struct typelist
|
||||||
|
{};
|
||||||
|
|
||||||
|
//invert_typelist
|
||||||
|
template<class T>
|
||||||
|
struct invert_typelist;
|
||||||
|
|
||||||
|
template<int I, typename Tuple>
|
||||||
|
struct typelist_element;
|
||||||
|
|
||||||
|
template<int I, typename Head, typename... Tail>
|
||||||
|
struct typelist_element<I, typelist<Head, Tail...> >
|
||||||
|
{
|
||||||
|
typedef typename typelist_element<I-1, typelist<Tail...> >::type type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<typename Head, typename... Tail>
|
||||||
|
struct typelist_element<0, typelist<Head, Tail...> >
|
||||||
|
{
|
||||||
|
typedef Head type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<int ...Ints, class ...Types>
|
||||||
|
typelist<typename typelist_element<(sizeof...(Types) - 1) - Ints, typelist<Types...> >::type...>
|
||||||
|
inverted_typelist(index_tuple<Ints...>, typelist<Types...>)
|
||||||
|
{
|
||||||
|
return typelist<typename typelist_element<(sizeof...(Types) - 1) - Ints, typelist<Types...> >::type...>();
|
||||||
|
}
|
||||||
|
|
||||||
|
//sizeof_typelist
|
||||||
|
template<class Typelist>
|
||||||
|
struct sizeof_typelist;
|
||||||
|
|
||||||
|
template<class ...Types>
|
||||||
|
struct sizeof_typelist< typelist<Types...> >
|
||||||
|
{
|
||||||
|
static const std::size_t value = sizeof...(Types);
|
||||||
|
};
|
||||||
|
|
||||||
|
//invert_typelist_impl
|
||||||
|
template<class Typelist, class Indexes>
|
||||||
|
struct invert_typelist_impl;
|
||||||
|
|
||||||
|
|
||||||
|
template<class Typelist, int ...Ints>
|
||||||
|
struct invert_typelist_impl< Typelist, index_tuple<Ints...> >
|
||||||
|
{
|
||||||
|
static const std::size_t last_idx = sizeof_typelist<Typelist>::value - 1;
|
||||||
|
typedef typelist
|
||||||
|
<typename typelist_element<last_idx - Ints, Typelist>::type...> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class Typelist, int Int>
|
||||||
|
struct invert_typelist_impl< Typelist, index_tuple<Int> >
|
||||||
|
{
|
||||||
|
typedef Typelist type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class Typelist>
|
||||||
|
struct invert_typelist_impl< Typelist, index_tuple<> >
|
||||||
|
{
|
||||||
|
typedef Typelist type;
|
||||||
|
};
|
||||||
|
|
||||||
|
//invert_typelist
|
||||||
|
template<class Typelist>
|
||||||
|
struct invert_typelist;
|
||||||
|
|
||||||
|
template<class ...Types>
|
||||||
|
struct invert_typelist< typelist<Types...> >
|
||||||
|
{
|
||||||
|
typedef typelist<Types...> typelist_t;
|
||||||
|
typedef typename build_number_seq<sizeof...(Types)>::type indexes_t;
|
||||||
|
typedef typename invert_typelist_impl<typelist_t, indexes_t>::type type;
|
||||||
|
};
|
||||||
|
|
||||||
|
//Do pack
|
||||||
|
template<class Typelist>
|
||||||
|
struct do_pack;
|
||||||
|
|
||||||
|
template<>
|
||||||
|
struct do_pack<typelist<> >;
|
||||||
|
|
||||||
|
template<class Prev>
|
||||||
|
struct do_pack<typelist<Prev> >
|
||||||
|
{
|
||||||
|
typedef Prev type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class Prev, class Last>
|
||||||
|
struct do_pack<typelist<Prev, Last> >
|
||||||
|
{
|
||||||
|
typedef typename Prev::template pack<Last> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
template<class Prev, class ...Others>
|
||||||
|
struct do_pack<typelist<Prev, Others...> >
|
||||||
|
{
|
||||||
|
typedef typename Prev::template pack
|
||||||
|
<typename do_pack<typelist<Others...> >::type> type;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
template<class DefaultOptions, class ...Options>
|
||||||
|
struct pack_options
|
||||||
|
{
|
||||||
|
typedef typelist<DefaultOptions, Options...> typelist_t;
|
||||||
|
typedef typename invert_typelist<typelist_t>::type inverted_typelist;
|
||||||
|
typedef typename do_pack<inverted_typelist>::type type;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif //!defined(BOOST_INTRUSIVE_VARIADIC_TEMPLATES)
|
||||||
|
|
||||||
|
#define BOOST_INTRUSIVE_OPTION_TYPE(OPTION_NAME, TYPE, TYPEDEF_EXPR, TYPEDEF_NAME) \
|
||||||
|
template< class TYPE> \
|
||||||
|
struct OPTION_NAME \
|
||||||
|
{ \
|
||||||
|
template<class Base> \
|
||||||
|
struct pack : Base \
|
||||||
|
{ \
|
||||||
|
typedef TYPEDEF_EXPR TYPEDEF_NAME; \
|
||||||
|
}; \
|
||||||
|
}; \
|
||||||
|
//
|
||||||
|
|
||||||
|
#define BOOST_INTRUSIVE_OPTION_CONSTANT(OPTION_NAME, TYPE, VALUE, CONSTANT_NAME) \
|
||||||
|
template< TYPE VALUE> \
|
||||||
|
struct OPTION_NAME \
|
||||||
|
{ \
|
||||||
|
template<class Base> \
|
||||||
|
struct pack : Base \
|
||||||
|
{ \
|
||||||
|
static const TYPE CONSTANT_NAME = VALUE; \
|
||||||
|
}; \
|
||||||
|
}; \
|
||||||
|
//
|
||||||
|
|
||||||
|
#else //#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||||
|
|
||||||
|
//! This class is a utility that takes:
|
||||||
|
//! - a default options class defining initial static constant
|
||||||
|
//! and typedefs
|
||||||
|
//! - several options defined with BOOST_INTRUSIVE_OPTION_CONSTANT and
|
||||||
|
//! BOOST_INTRUSIVE_OPTION_TYPE
|
||||||
|
//!
|
||||||
|
//! and packs them together in a new type that defines all options as
|
||||||
|
//! member typedefs or static constant values. Given options of form:
|
||||||
|
//!
|
||||||
|
//! \code
|
||||||
|
//! BOOST_INTRUSIVE_OPTION_TYPE(my_pointer, VoidPointer, VoidPointer, my_pointer_type)
|
||||||
|
//! BOOST_INTRUSIVE_OPTION_CONSTANT(incremental, bool, Enabled, is_incremental)
|
||||||
|
//! \endcode
|
||||||
|
//!
|
||||||
|
//! the following expression
|
||||||
|
//!
|
||||||
|
//! \code
|
||||||
|
//!
|
||||||
|
//! struct default_options
|
||||||
|
//! {
|
||||||
|
//! typedef long int_type;
|
||||||
|
//! static const int int_constant = -1;
|
||||||
|
//! };
|
||||||
|
//!
|
||||||
|
//! pack_options< default_options, my_pointer<void*>, incremental<true> >::type
|
||||||
|
//! \endcode
|
||||||
|
//!
|
||||||
|
//! will create a type that will contain the following typedefs/constants
|
||||||
|
//!
|
||||||
|
//! \code
|
||||||
|
//! struct unspecified_type
|
||||||
|
//! {
|
||||||
|
//! //Default options
|
||||||
|
//! typedef long int_type;
|
||||||
|
//! static const int int_constant = -1;
|
||||||
|
//!
|
||||||
|
//! //Packed options (will ovewrite any default option)
|
||||||
|
//! typedef void* my_pointer_type;
|
||||||
|
//! static const bool is_incremental = true;
|
||||||
|
//! };
|
||||||
|
//! \endcode
|
||||||
|
//!
|
||||||
|
//! If an option is specified in the default options argument and later
|
||||||
|
//! redefined as an option, the last definition will prevail.
|
||||||
|
template<class DefaultOptions, class ...Options>
|
||||||
|
struct pack_options
|
||||||
|
{
|
||||||
|
typedef unspecified_type type;
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Defines an option class of name OPTION_NAME that can be used to specify a type
|
||||||
|
//! of type TYPE...
|
||||||
|
//!
|
||||||
|
//! \code
|
||||||
|
//! struct OPTION_NAME<class TYPE>
|
||||||
|
//! { /*unspecified_content*/ };
|
||||||
|
//! \endcode
|
||||||
|
//!
|
||||||
|
//! ...that after being combined with
|
||||||
|
//! <code>boost::intrusive::pack_options</code>,
|
||||||
|
//! will typedef TYPE as a typedef of name TYPEDEF_NAME. Example:
|
||||||
|
//!
|
||||||
|
//! \code
|
||||||
|
//! //[includes and namespaces omitted for brevity]
|
||||||
|
//!
|
||||||
|
//! //This macro will create the following class:
|
||||||
|
//! // template<class VoidPointer>
|
||||||
|
//! // struct my_pointer
|
||||||
|
//! // { unspecified_content };
|
||||||
|
//! BOOST_INTRUSIVE_OPTION_TYPE(my_pointer, VoidPointer, boost::remove_pointer<VoidPointer>::type, my_pointer_type)
|
||||||
|
//!
|
||||||
|
//! struct empty_default{};
|
||||||
|
//!
|
||||||
|
//! typedef pack_options< empty_default, typename my_pointer<void*> >::type::my_pointer_type type;
|
||||||
|
//!
|
||||||
|
//! BOOST_STATIC_ASSERT(( boost::is_same<type, void>::value ));
|
||||||
|
//!
|
||||||
|
//! \endcode
|
||||||
|
#define BOOST_INTRUSIVE_OPTION_TYPE(OPTION_NAME, TYPE, TYPEDEF_EXPR, TYPEDEF_NAME)
|
||||||
|
|
||||||
|
//! Defines an option class of name OPTION_NAME that can be used to specify a constant
|
||||||
|
//! of type TYPE with value VALUE...
|
||||||
|
//!
|
||||||
|
//! \code
|
||||||
|
//! struct OPTION_NAME<TYPE VALUE>
|
||||||
|
//! { /*unspecified_content*/ };
|
||||||
|
//! \endcode
|
||||||
|
//!
|
||||||
|
//! ...that after being combined with
|
||||||
|
//! <code>boost::intrusive::pack_options</code>,
|
||||||
|
//! will contain a CONSTANT_NAME static constant of value VALUE. Example:
|
||||||
|
//!
|
||||||
|
//! \code
|
||||||
|
//! //[includes and namespaces omitted for brevity]
|
||||||
|
//!
|
||||||
|
//! //This macro will create the following class:
|
||||||
|
//! // template<bool Enabled>
|
||||||
|
//! // struct incremental
|
||||||
|
//! // { unspecified_content };
|
||||||
|
//! BOOST_INTRUSIVE_OPTION_CONSTANT(incremental, bool, Enabled, is_incremental)
|
||||||
|
//!
|
||||||
|
//! struct empty_default{};
|
||||||
|
//!
|
||||||
|
//! const bool is_incremental = pack_options< empty_default, incremental<true> >::type::is_incremental;
|
||||||
|
//!
|
||||||
|
//! BOOST_STATIC_ASSERT(( is_incremental == true ));
|
||||||
|
//!
|
||||||
|
//! \endcode
|
||||||
|
#define BOOST_INTRUSIVE_OPTION_CONSTANT(OPTION_NAME, TYPE, VALUE, CONSTANT_NAME)
|
||||||
|
|
||||||
|
#endif //#ifndef BOOST_INTRUSIVE_DOXYGEN_INVOKED
|
||||||
|
|
||||||
|
|
||||||
|
} //namespace intrusive {
|
||||||
|
} //namespace boost {
|
||||||
|
|
||||||
|
#include <boost/intrusive/detail/config_end.hpp>
|
||||||
|
|
||||||
|
#endif //#ifndef BOOST_INTRUSIVE_PACK_OPTIONS_HPP
|
@@ -115,6 +115,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "scary_iterators", "scary_it
|
|||||||
ProjectSection(ProjectDependencies) = postProject
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
EndProjectSection
|
EndProjectSection
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pack_options", "pack_options\pack_options.vcproj", "{77F4139B-281B-F694-7CB1-3495467B4D35}"
|
||||||
|
ProjectSection(ProjectDependencies) = postProject
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfiguration) = preSolution
|
GlobalSection(SolutionConfiguration) = preSolution
|
||||||
Debug = Debug
|
Debug = Debug
|
||||||
@@ -239,6 +243,10 @@ Global
|
|||||||
{7679B41B-C1C5-FA34-9614-3547B3140346}.Debug.Build.0 = Debug|Win32
|
{7679B41B-C1C5-FA34-9614-3547B3140346}.Debug.Build.0 = Debug|Win32
|
||||||
{7679B41B-C1C5-FA34-9614-3547B3140346}.Release.ActiveCfg = Release|Win32
|
{7679B41B-C1C5-FA34-9614-3547B3140346}.Release.ActiveCfg = Release|Win32
|
||||||
{7679B41B-C1C5-FA34-9614-3547B3140346}.Release.Build.0 = Release|Win32
|
{7679B41B-C1C5-FA34-9614-3547B3140346}.Release.Build.0 = Release|Win32
|
||||||
|
{77F4139B-281B-F694-7CB1-3495467B4D35}.Debug.ActiveCfg = Debug|Win32
|
||||||
|
{77F4139B-281B-F694-7CB1-3495467B4D35}.Debug.Build.0 = Debug|Win32
|
||||||
|
{77F4139B-281B-F694-7CB1-3495467B4D35}.Release.ActiveCfg = Release|Win32
|
||||||
|
{77F4139B-281B-F694-7CB1-3495467B4D35}.Release.Build.0 = Release|Win32
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
|
@@ -157,6 +157,9 @@
|
|||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\..\..\boost\intrusive\options.hpp">
|
RelativePath="..\..\..\..\..\boost\intrusive\options.hpp">
|
||||||
</File>
|
</File>
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\..\..\boost\intrusive\pack_options.hpp">
|
||||||
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath="..\..\..\..\..\boost\intrusive\parent_from_member.hpp">
|
RelativePath="..\..\..\..\..\boost\intrusive\parent_from_member.hpp">
|
||||||
</File>
|
</File>
|
||||||
|
133
proj/vc7ide/pack_options/pack_options.vcproj
Normal file
133
proj/vc7ide/pack_options/pack_options.vcproj
Normal file
@@ -0,0 +1,133 @@
|
|||||||
|
<?xml version="1.0" encoding="Windows-1252"?>
|
||||||
|
<VisualStudioProject
|
||||||
|
ProjectType="Visual C++"
|
||||||
|
Version="7.10"
|
||||||
|
Name="pack_options"
|
||||||
|
ProjectGUID="{77F4139B-281B-F694-7CB1-3495467B4D35}"
|
||||||
|
RootNamespace="pack_options"
|
||||||
|
Keyword="Win32Proj">
|
||||||
|
<Platforms>
|
||||||
|
<Platform
|
||||||
|
Name="Win32"/>
|
||||||
|
</Platforms>
|
||||||
|
<Configurations>
|
||||||
|
<Configuration
|
||||||
|
Name="Debug|Win32"
|
||||||
|
OutputDirectory="Debug"
|
||||||
|
IntermediateDirectory="Debug"
|
||||||
|
ConfigurationType="1"
|
||||||
|
CharacterSet="2">
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
Optimization="0"
|
||||||
|
AdditionalIncludeDirectories="../../../../../"
|
||||||
|
PreprocessorDefinitions="BOOST_DATE_TIME_NO_LIB"
|
||||||
|
GeneratePreprocessedFile="0"
|
||||||
|
KeepComments="FALSE"
|
||||||
|
MinimalRebuild="TRUE"
|
||||||
|
BasicRuntimeChecks="3"
|
||||||
|
RuntimeLibrary="5"
|
||||||
|
DisableLanguageExtensions="FALSE"
|
||||||
|
TreatWChar_tAsBuiltInType="TRUE"
|
||||||
|
ForceConformanceInForLoopScope="TRUE"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="4"
|
||||||
|
Detect64BitPortabilityProblems="TRUE"
|
||||||
|
DebugInformationFormat="4"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
OutputFile="$(OutDir)/pack_options.exe"
|
||||||
|
LinkIncremental="2"
|
||||||
|
GenerateDebugInformation="TRUE"
|
||||||
|
ProgramDatabaseFile="$(OutDir)/pack_options.pdb"
|
||||||
|
GenerateMapFile="TRUE"
|
||||||
|
SubSystem="1"
|
||||||
|
TargetMachine="1"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebDeploymentTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedWrapperGeneratorTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||||
|
</Configuration>
|
||||||
|
<Configuration
|
||||||
|
Name="Release|Win32"
|
||||||
|
OutputDirectory="Release"
|
||||||
|
IntermediateDirectory="Release"
|
||||||
|
ConfigurationType="1"
|
||||||
|
CharacterSet="2">
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
AdditionalIncludeDirectories="../../../../../"
|
||||||
|
PreprocessorDefinitions="BOOST_DATE_TIME_NO_LIB"
|
||||||
|
RuntimeLibrary="4"
|
||||||
|
DisableLanguageExtensions="FALSE"
|
||||||
|
ForceConformanceInForLoopScope="TRUE"
|
||||||
|
UsePrecompiledHeader="0"
|
||||||
|
WarningLevel="3"
|
||||||
|
Detect64BitPortabilityProblems="TRUE"
|
||||||
|
DebugInformationFormat="3"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCCustomBuildTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCLinkerTool"
|
||||||
|
OutputFile="$(OutDir)/pack_options.exe"
|
||||||
|
LinkIncremental="1"
|
||||||
|
GenerateDebugInformation="TRUE"
|
||||||
|
SubSystem="1"
|
||||||
|
OptimizeReferences="2"
|
||||||
|
EnableCOMDATFolding="2"
|
||||||
|
TargetMachine="1"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCMIDLTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPostBuildEventTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreBuildEventTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCPreLinkEventTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCResourceCompilerTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebServiceProxyGeneratorTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCXMLDataGeneratorTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCWebDeploymentTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCManagedWrapperGeneratorTool"/>
|
||||||
|
<Tool
|
||||||
|
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
|
||||||
|
</Configuration>
|
||||||
|
</Configurations>
|
||||||
|
<References>
|
||||||
|
</References>
|
||||||
|
<Files>
|
||||||
|
<Filter
|
||||||
|
Name="Source Files"
|
||||||
|
Filter="cpp;c;cxx;def;odl;idl;hpj;bat;asm;asmx"
|
||||||
|
UniqueIdentifier="{47FFA531-6474-B5A5-A661-272FA537F35F}">
|
||||||
|
<File
|
||||||
|
RelativePath="..\..\..\test\pack_options_test.cpp">
|
||||||
|
</File>
|
||||||
|
</Filter>
|
||||||
|
</Files>
|
||||||
|
<Globals>
|
||||||
|
</Globals>
|
||||||
|
</VisualStudioProject>
|
@@ -21,6 +21,7 @@
|
|||||||
Optimization="0"
|
Optimization="0"
|
||||||
AdditionalIncludeDirectories="../../../../../"
|
AdditionalIncludeDirectories="../../../../../"
|
||||||
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE"
|
||||||
|
GeneratePreprocessedFile="0"
|
||||||
MinimalRebuild="TRUE"
|
MinimalRebuild="TRUE"
|
||||||
BasicRuntimeChecks="3"
|
BasicRuntimeChecks="3"
|
||||||
RuntimeLibrary="5"
|
RuntimeLibrary="5"
|
||||||
|
60
test/pack_options_test.cpp
Normal file
60
test/pack_options_test.cpp
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// (C) Copyright Ion Gaztanaga 2013-2013. 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)
|
||||||
|
//
|
||||||
|
// See http://www.boost.org/libs/intrusive for documentation.
|
||||||
|
//
|
||||||
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
#include <boost/intrusive/detail/config_begin.hpp>
|
||||||
|
#include <boost/type_traits/is_same.hpp>
|
||||||
|
#include <boost/type_traits/remove_pointer.hpp>
|
||||||
|
#include <boost/type_traits/add_pointer.hpp>
|
||||||
|
#include <boost/static_assert.hpp>
|
||||||
|
#include <boost/intrusive/pack_options.hpp>
|
||||||
|
|
||||||
|
struct empty_default{};
|
||||||
|
|
||||||
|
using namespace boost::intrusive;
|
||||||
|
|
||||||
|
//Test BOOST_INTRUSIVE_OPTION_CONSTANT
|
||||||
|
BOOST_INTRUSIVE_OPTION_CONSTANT(incremental, bool, Enabled, is_incremental)
|
||||||
|
const bool is_incremental_value = pack_options< empty_default, incremental<true> >::type::is_incremental;
|
||||||
|
BOOST_STATIC_ASSERT(( is_incremental_value == true ));
|
||||||
|
|
||||||
|
//Test BOOST_INTRUSIVE_OPTION_TYPE
|
||||||
|
BOOST_INTRUSIVE_OPTION_TYPE(my_pointer, VoidPointer, typename boost::remove_pointer<VoidPointer>::type, my_pointer_type)
|
||||||
|
typedef pack_options< empty_default, my_pointer<void*> >::type::my_pointer_type my_pointer_type;
|
||||||
|
BOOST_STATIC_ASSERT(( boost::is_same<my_pointer_type, void>::value ));
|
||||||
|
|
||||||
|
//test combination of BOOST_INTRUSIVE_OPTION_CONSTANT and BOOST_INTRUSIVE_OPTION_TYPE
|
||||||
|
// First add new options
|
||||||
|
struct default_options
|
||||||
|
{
|
||||||
|
static const long long_constant = -3;
|
||||||
|
typedef double * double_typedef;
|
||||||
|
};
|
||||||
|
|
||||||
|
BOOST_INTRUSIVE_OPTION_CONSTANT(incremental2, bool, Enabled, is_incremental2)
|
||||||
|
BOOST_INTRUSIVE_OPTION_TYPE(my_pointer2, VoidPointer, typename boost::add_pointer<VoidPointer>::type, my_pointer_type2)
|
||||||
|
typedef pack_options < default_options
|
||||||
|
, incremental<false>
|
||||||
|
, my_pointer<float*>
|
||||||
|
, incremental2<true>
|
||||||
|
, my_pointer2<const char*>
|
||||||
|
>::type combined_type;
|
||||||
|
BOOST_STATIC_ASSERT(( combined_type::is_incremental == false ));
|
||||||
|
BOOST_STATIC_ASSERT(( combined_type::is_incremental2 == true ));
|
||||||
|
BOOST_STATIC_ASSERT(( boost::is_same<combined_type::my_pointer_type, float >::value ));
|
||||||
|
BOOST_STATIC_ASSERT(( boost::is_same<combined_type::my_pointer_type2, const char**>::value ));
|
||||||
|
|
||||||
|
//test packing the default options leads to a default options type
|
||||||
|
BOOST_STATIC_ASSERT(( boost::is_same<pack_options<default_options>::type, default_options>::value ));
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#include <boost/intrusive/detail/config_end.hpp>
|
Reference in New Issue
Block a user