mirror of
https://github.com/boostorg/detail.git
synced 2025-07-29 11:57:15 +02:00
Compare commits
38 Commits
boost-1.24
...
boost-1.30
Author | SHA1 | Date | |
---|---|---|---|
e7570a1aa0 | |||
1cadc9c575 | |||
124be84389 | |||
0caf4bb53e | |||
7f668adbcd | |||
d6fbac9ba7 | |||
8f71074339 | |||
1f52127735 | |||
48507564a9 | |||
8d549f45fd | |||
c1f144e5d4 | |||
53ba30e0c9 | |||
9aead1823b | |||
c14ee17601 | |||
2bca71488b | |||
1f335d30ba | |||
a38297a6cc | |||
72ca3d7d9f | |||
28432648e0 | |||
e69140d3f3 | |||
00f6a9751a | |||
9663499093 | |||
d9d6a970cf | |||
5efbcbea28 | |||
01448d3373 | |||
15a5375b14 | |||
09e0b2e072 | |||
08e37c5ccc | |||
19201a4bb9 | |||
528fb22617 | |||
71790af7f6 | |||
59099cadf6 | |||
695b3059bd | |||
3a4ed6ef7c | |||
63b5e51676 | |||
8c6c8f9604 | |||
865bc7d803 | |||
0ea958903a |
@ -5,7 +5,7 @@
|
||||
// appears in all copies. This software is provided "as is" without express or
|
||||
// implied warranty, and with no claim as to its suitability for any purpose.
|
||||
|
||||
// See http://www.boost.org for updates and documentation.
|
||||
// See http://www.boost.org/libs/utility/cstdlib.html for documentation.
|
||||
|
||||
// Revision History
|
||||
// 26 Feb 01 Initial version (Beman Dawes)
|
||||
|
283
include/boost/detail/allocator.hpp
Normal file
283
include/boost/detail/allocator.hpp
Normal file
@ -0,0 +1,283 @@
|
||||
/*
|
||||
*
|
||||
* Copyright (c) 2001
|
||||
* Dr John Maddock
|
||||
*
|
||||
* Permission to use, copy, modify, distribute and sell this software
|
||||
* and its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and
|
||||
* that both that copyright notice and this permission notice appear
|
||||
* in supporting documentation. Dr John Maddock makes no representations
|
||||
* about the suitability of this software for any purpose.
|
||||
* It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef BOOST_DETAIL_ALLOCATOR_HPP
|
||||
#define BOOST_DETAIL_ALLOCATOR_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <cstdlib>
|
||||
#if defined(BOOST_NO_STDC_NAMESPACE)
|
||||
namespace std{
|
||||
using ::ptrdiff_t;
|
||||
using ::size_t;
|
||||
}
|
||||
#endif
|
||||
|
||||
// see if we have SGI alloc class:
|
||||
#if defined(BOOST_NO_STD_ALLOCATOR) && (defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION) || defined(__GLIBCPP__) || defined(__STL_CONFIG_H))
|
||||
# define BOOST_HAVE_SGI_ALLOCATOR
|
||||
# include <memory>
|
||||
# if defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)
|
||||
namespace boost{ namespace detail{
|
||||
typedef std::__sgi_alloc alloc_type;
|
||||
}}
|
||||
# else
|
||||
namespace boost{ namespace detail{
|
||||
typedef std::alloc alloc_type;
|
||||
}}
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
namespace boost{ namespace detail{
|
||||
|
||||
template <class T>
|
||||
void allocator_construct(T* p, const T& t)
|
||||
{ new (p) T(t); }
|
||||
|
||||
template <class T>
|
||||
void allocator_destroy(T* p)
|
||||
{
|
||||
(void)p; // warning suppression
|
||||
p->~T();
|
||||
}
|
||||
|
||||
} }
|
||||
|
||||
#if !defined(BOOST_NO_STD_ALLOCATOR)
|
||||
|
||||
#include <memory>
|
||||
|
||||
#define BOOST_DEFAULT_ALLOCATOR(T) std::allocator< T >
|
||||
|
||||
namespace boost{ namespace detail{
|
||||
|
||||
template <class T, class A>
|
||||
struct rebind_allocator
|
||||
{
|
||||
typedef typename A::template rebind<T> binder;
|
||||
typedef typename binder::other type;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace boost
|
||||
|
||||
#elif !defined(BOOST_NO_MEMBER_TEMPLATES)
|
||||
|
||||
// no std::allocator, but the compiler supports the necessary syntax,
|
||||
// write our own allocator instead:
|
||||
|
||||
#define BOOST_DEFAULT_ALLOCATOR(T) ::boost::detail::allocator< T >
|
||||
|
||||
namespace boost{ namespace detail{
|
||||
|
||||
template <class T>
|
||||
class allocator
|
||||
{
|
||||
public:
|
||||
|
||||
typedef T value_type;
|
||||
typedef value_type * pointer;
|
||||
typedef const T* const_pointer;
|
||||
typedef T& reference;
|
||||
typedef const T& const_reference;
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
|
||||
template <class U>
|
||||
struct rebind
|
||||
{
|
||||
typedef allocator<U> other;
|
||||
};
|
||||
|
||||
allocator(){}
|
||||
|
||||
template <class U>
|
||||
allocator(const allocator<U>&){}
|
||||
|
||||
allocator(const allocator&){}
|
||||
|
||||
template <class U>
|
||||
allocator& operator=(const allocator<U>&)
|
||||
{ return *this; }
|
||||
|
||||
~allocator(){}
|
||||
|
||||
pointer address(reference x) { return &x; }
|
||||
|
||||
const_pointer address(const_reference x) const { return &x; }
|
||||
|
||||
pointer allocate(size_type n, const void* = 0)
|
||||
{
|
||||
#ifdef BOOST_HAVE_SGI_ALLOCATOR
|
||||
return n != 0 ?
|
||||
reinterpret_cast<pointer>(alloc_type::allocate(n * sizeof(value_type)))
|
||||
: 0;
|
||||
#else
|
||||
return n != 0 ?
|
||||
reinterpret_cast<pointer>(::operator new(n * sizeof(value_type)))
|
||||
: 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void deallocate(pointer p, size_type n)
|
||||
{
|
||||
#ifdef BOOST_HAVE_SGI_ALLOCATOR
|
||||
assert( (p == 0) == (n == 0) );
|
||||
if (p != 0)
|
||||
alloc_type::deallocate((void*)p, n);
|
||||
#else
|
||||
assert( (p == 0) == (n == 0) );
|
||||
if (p != 0)
|
||||
::operator delete((void*)p);
|
||||
#endif
|
||||
}
|
||||
|
||||
size_type max_size() const
|
||||
{ return size_t(-1) / sizeof(value_type); }
|
||||
|
||||
void construct(pointer p, const T& val) const
|
||||
{ allocator_construct(p, val); }
|
||||
|
||||
void destroy(pointer p) const
|
||||
{ allocator_destroy(p); }
|
||||
};
|
||||
|
||||
template <class T, class A>
|
||||
struct rebind_allocator
|
||||
{
|
||||
typedef typename A::template rebind<T> binder;
|
||||
typedef typename binder::other type;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace boost
|
||||
|
||||
#else
|
||||
|
||||
// no std::allocator, use workaround version instead,
|
||||
// each allocator class must derive from a base class
|
||||
// that allocates blocks of bytes:
|
||||
|
||||
#define BOOST_DEFAULT_ALLOCATOR(T) ::boost::detail::allocator_adapter<T, ::boost::detail::simple_alloc>
|
||||
|
||||
namespace boost{ namespace detail{
|
||||
|
||||
class simple_alloc
|
||||
{
|
||||
public:
|
||||
|
||||
typedef void value_type;
|
||||
typedef value_type * pointer;
|
||||
typedef const void* const_pointer;
|
||||
typedef std::size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
|
||||
simple_alloc(){}
|
||||
simple_alloc(const simple_alloc&){}
|
||||
|
||||
~simple_alloc(){}
|
||||
|
||||
pointer allocate(size_type n, const void* = 0)
|
||||
{
|
||||
#ifdef BOOST_HAVE_SGI_ALLOCATOR
|
||||
return n != 0 ?
|
||||
reinterpret_cast<pointer>(alloc_type::allocate(n))
|
||||
: 0;
|
||||
#else
|
||||
return n != 0 ?
|
||||
reinterpret_cast<pointer>(::operator new(n))
|
||||
: 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
void deallocate(pointer p, size_type n)
|
||||
{
|
||||
#ifdef BOOST_HAVE_SGI_ALLOCATOR
|
||||
assert( (p == 0) == (n == 0) );
|
||||
if (p != 0)
|
||||
alloc_type::deallocate((void*)p, n);
|
||||
#else
|
||||
assert( (p == 0) == (n == 0) );
|
||||
if (p != 0)
|
||||
::operator delete((void*)p);
|
||||
#endif
|
||||
}
|
||||
};
|
||||
|
||||
template <class T, class Base>
|
||||
class allocator_adapter : public Base
|
||||
{
|
||||
public:
|
||||
|
||||
typedef T value_type;
|
||||
typedef value_type * pointer;
|
||||
typedef const T* const_pointer;
|
||||
typedef T& reference;
|
||||
typedef const T& const_reference;
|
||||
typedef size_t size_type;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef Base base_type;
|
||||
|
||||
allocator_adapter(){}
|
||||
allocator_adapter(const base_type& x) : Base(x){}
|
||||
allocator_adapter& operator=(const base_type& x)
|
||||
{
|
||||
*(static_cast<base_type*>(this)) = x;
|
||||
return *this;
|
||||
}
|
||||
|
||||
~allocator_adapter(){}
|
||||
|
||||
pointer address(reference x) { return &x; }
|
||||
|
||||
const_pointer address(const_reference x) const { return &x; }
|
||||
|
||||
pointer allocate(size_type n, const void* = 0)
|
||||
{
|
||||
return n != 0 ?
|
||||
reinterpret_cast<pointer>(base_type::allocate(n * sizeof(value_type)))
|
||||
: 0;
|
||||
}
|
||||
|
||||
void deallocate(pointer p, size_type n)
|
||||
{
|
||||
assert( (p == 0) == (n == 0) );
|
||||
if (p != 0)
|
||||
static_cast<base_type*>(this)->deallocate((void*)p, n * sizeof(value_type));
|
||||
}
|
||||
|
||||
size_type max_size() const
|
||||
{ return size_t(-1) / sizeof(value_type); }
|
||||
|
||||
void construct(pointer p, const T& val) const
|
||||
{ allocator_construct(p, val); }
|
||||
|
||||
void destroy(pointer p) const
|
||||
{ allocator_destroy(p); }
|
||||
};
|
||||
|
||||
template <class T, class A>
|
||||
struct rebind_allocator
|
||||
{
|
||||
typedef allocator_adapter<T, typename A::base_type> type;
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
} // namespace boost
|
||||
|
||||
#endif
|
||||
|
||||
#endif // include guard
|
217
include/boost/detail/binary_search.hpp
Normal file
217
include/boost/detail/binary_search.hpp
Normal file
@ -0,0 +1,217 @@
|
||||
// Copyright (c) 2000 David Abrahams. Permission to copy, use, modify,
|
||||
// sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
//
|
||||
// Copyright (c) 1994
|
||||
// Hewlett-Packard Company
|
||||
//
|
||||
// Permission to use, copy, modify, distribute and sell this software
|
||||
// and its documentation for any purpose is hereby granted without fee,
|
||||
// provided that the above copyright notice appear in all copies and
|
||||
// that both that copyright notice and this permission notice appear
|
||||
// in supporting documentation. Hewlett-Packard Company makes no
|
||||
// representations about the suitability of this software for any
|
||||
// purpose. It is provided "as is" without express or implied warranty.
|
||||
//
|
||||
// Copyright (c) 1996
|
||||
// Silicon Graphics Computer Systems, Inc.
|
||||
//
|
||||
// Permission to use, copy, modify, distribute and sell this software
|
||||
// and its documentation for any purpose is hereby granted without fee,
|
||||
// provided that the above copyright notice appear in all copies and
|
||||
// that both that copyright notice and this permission notice appear
|
||||
// in supporting documentation. Silicon Graphics makes no
|
||||
// representations about the suitability of this software for any
|
||||
// purpose. It is provided "as is" without express or implied warranty.
|
||||
//
|
||||
#ifndef BINARY_SEARCH_DWA_122600_H_
|
||||
# define BINARY_SEARCH_DWA_122600_H_
|
||||
|
||||
# include <boost/detail/iterator.hpp>
|
||||
# include <utility>
|
||||
|
||||
namespace boost { namespace detail {
|
||||
|
||||
template <class ForwardIter, class Tp>
|
||||
ForwardIter lower_bound(ForwardIter first, ForwardIter last,
|
||||
const Tp& val)
|
||||
{
|
||||
typedef detail::iterator_traits<ForwardIter> traits;
|
||||
|
||||
typename traits::difference_type len = boost::detail::distance(first, last);
|
||||
typename traits::difference_type half;
|
||||
ForwardIter middle;
|
||||
|
||||
while (len > 0) {
|
||||
half = len >> 1;
|
||||
middle = first;
|
||||
std::advance(middle, half);
|
||||
if (*middle < val) {
|
||||
first = middle;
|
||||
++first;
|
||||
len = len - half - 1;
|
||||
}
|
||||
else
|
||||
len = half;
|
||||
}
|
||||
return first;
|
||||
}
|
||||
|
||||
template <class ForwardIter, class Tp, class Compare>
|
||||
ForwardIter lower_bound(ForwardIter first, ForwardIter last,
|
||||
const Tp& val, Compare comp)
|
||||
{
|
||||
typedef detail::iterator_traits<ForwardIter> traits;
|
||||
|
||||
typename traits::difference_type len = boost::detail::distance(first, last);
|
||||
typename traits::difference_type half;
|
||||
ForwardIter middle;
|
||||
|
||||
while (len > 0) {
|
||||
half = len >> 1;
|
||||
middle = first;
|
||||
std::advance(middle, half);
|
||||
if (comp(*middle, val)) {
|
||||
first = middle;
|
||||
++first;
|
||||
len = len - half - 1;
|
||||
}
|
||||
else
|
||||
len = half;
|
||||
}
|
||||
return first;
|
||||
}
|
||||
|
||||
template <class ForwardIter, class Tp>
|
||||
ForwardIter upper_bound(ForwardIter first, ForwardIter last,
|
||||
const Tp& val)
|
||||
{
|
||||
typedef detail::iterator_traits<ForwardIter> traits;
|
||||
|
||||
typename traits::difference_type len = boost::detail::distance(first, last);
|
||||
typename traits::difference_type half;
|
||||
ForwardIter middle;
|
||||
|
||||
while (len > 0) {
|
||||
half = len >> 1;
|
||||
middle = first;
|
||||
std::advance(middle, half);
|
||||
if (val < *middle)
|
||||
len = half;
|
||||
else {
|
||||
first = middle;
|
||||
++first;
|
||||
len = len - half - 1;
|
||||
}
|
||||
}
|
||||
return first;
|
||||
}
|
||||
|
||||
template <class ForwardIter, class Tp, class Compare>
|
||||
ForwardIter upper_bound(ForwardIter first, ForwardIter last,
|
||||
const Tp& val, Compare comp)
|
||||
{
|
||||
typedef detail::iterator_traits<ForwardIter> traits;
|
||||
|
||||
typename traits::difference_type len = boost::detail::distance(first, last);
|
||||
typename traits::difference_type half;
|
||||
ForwardIter middle;
|
||||
|
||||
while (len > 0) {
|
||||
half = len >> 1;
|
||||
middle = first;
|
||||
std::advance(middle, half);
|
||||
if (comp(val, *middle))
|
||||
len = half;
|
||||
else {
|
||||
first = middle;
|
||||
++first;
|
||||
len = len - half - 1;
|
||||
}
|
||||
}
|
||||
return first;
|
||||
}
|
||||
|
||||
template <class ForwardIter, class Tp>
|
||||
std::pair<ForwardIter, ForwardIter>
|
||||
equal_range(ForwardIter first, ForwardIter last, const Tp& val)
|
||||
{
|
||||
typedef detail::iterator_traits<ForwardIter> traits;
|
||||
|
||||
typename traits::difference_type len = boost::detail::distance(first, last);
|
||||
typename traits::difference_type half;
|
||||
ForwardIter middle, left, right;
|
||||
|
||||
while (len > 0) {
|
||||
half = len >> 1;
|
||||
middle = first;
|
||||
std::advance(middle, half);
|
||||
if (*middle < val) {
|
||||
first = middle;
|
||||
++first;
|
||||
len = len - half - 1;
|
||||
}
|
||||
else if (val < *middle)
|
||||
len = half;
|
||||
else {
|
||||
left = boost::detail::lower_bound(first, middle, val);
|
||||
std::advance(first, len);
|
||||
right = boost::detail::upper_bound(++middle, first, val);
|
||||
return std::pair<ForwardIter, ForwardIter>(left, right);
|
||||
}
|
||||
}
|
||||
return std::pair<ForwardIter, ForwardIter>(first, first);
|
||||
}
|
||||
|
||||
template <class ForwardIter, class Tp, class Compare>
|
||||
std::pair<ForwardIter, ForwardIter>
|
||||
equal_range(ForwardIter first, ForwardIter last, const Tp& val,
|
||||
Compare comp)
|
||||
{
|
||||
typedef detail::iterator_traits<ForwardIter> traits;
|
||||
|
||||
typename traits::difference_type len = boost::detail::distance(first, last);
|
||||
typename traits::difference_type half;
|
||||
ForwardIter middle, left, right;
|
||||
|
||||
while (len > 0) {
|
||||
half = len >> 1;
|
||||
middle = first;
|
||||
std::advance(middle, half);
|
||||
if (comp(*middle, val)) {
|
||||
first = middle;
|
||||
++first;
|
||||
len = len - half - 1;
|
||||
}
|
||||
else if (comp(val, *middle))
|
||||
len = half;
|
||||
else {
|
||||
left = boost::detail::lower_bound(first, middle, val, comp);
|
||||
std::advance(first, len);
|
||||
right = boost::detail::upper_bound(++middle, first, val, comp);
|
||||
return std::pair<ForwardIter, ForwardIter>(left, right);
|
||||
}
|
||||
}
|
||||
return std::pair<ForwardIter, ForwardIter>(first, first);
|
||||
}
|
||||
|
||||
template <class ForwardIter, class Tp>
|
||||
bool binary_search(ForwardIter first, ForwardIter last,
|
||||
const Tp& val) {
|
||||
ForwardIter i = boost::detail::lower_bound(first, last, val);
|
||||
return i != last && !(val < *i);
|
||||
}
|
||||
|
||||
template <class ForwardIter, class Tp, class Compare>
|
||||
bool binary_search(ForwardIter first, ForwardIter last,
|
||||
const Tp& val,
|
||||
Compare comp) {
|
||||
ForwardIter i = boost::detail::lower_bound(first, last, val, comp);
|
||||
return i != last && !comp(val, *i);
|
||||
}
|
||||
|
||||
}} // namespace boost::detail
|
||||
|
||||
#endif // BINARY_SEARCH_DWA_122600_H_
|
@ -60,10 +60,13 @@ namespace boost
|
||||
int result = 0; // quiet compiler warnings
|
||||
bool exception_thrown = true; // avoid setting result for each excptn type
|
||||
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
try
|
||||
{
|
||||
#endif
|
||||
result = function_object();
|
||||
exception_thrown = false;
|
||||
#ifndef BOOST_NO_EXCEPTIONS
|
||||
}
|
||||
|
||||
// As a result of hard experience with strangely interleaved output
|
||||
@ -120,6 +123,7 @@ namespace boost
|
||||
|
||||
catch ( ... )
|
||||
{ detail::report_exception( out, "unknown exception", "" ); }
|
||||
#endif // BOOST_NO_EXCEPTIONS
|
||||
|
||||
if ( exception_thrown ) result = boost::exit_exception_failure;
|
||||
|
||||
@ -131,8 +135,9 @@ namespace boost
|
||||
<< "********** errors detected; see stdout for details ***********"
|
||||
<< std::endl;
|
||||
}
|
||||
#if !defined(BOOST_NO_CPP_MAIN_SUCCESS_MESSAGE)
|
||||
else { out << std::flush << "no errors detected" << std::endl; }
|
||||
|
||||
#endif
|
||||
return result;
|
||||
} // catch_exceptions
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
// (C) Copyright David Abrahams 2001. Permission to copy, use, modify,
|
||||
// (C) Copyright David Abrahams 2002. Permission to copy, use, modify,
|
||||
// sell and distribute this software is granted provided this
|
||||
// copyright notice appears in all copies. This software is provided
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
@ -20,11 +20,6 @@
|
||||
// std::iterator_traits<X>::pointer
|
||||
// std::iterator_traits<X>::reference
|
||||
//
|
||||
// CAVEAT: When using the VC6 standard library, an iterator derived from
|
||||
// std::iterator but not boost::iterator or from one supplied by the standard
|
||||
// will always have pointer == const value_type* and reference == const
|
||||
// value_type&, whether that's correct or not.
|
||||
|
||||
// See http://www.boost.org for most recent version including documentation.
|
||||
|
||||
// Revision History
|
||||
@ -57,21 +52,17 @@
|
||||
# define ITERATOR_DWA122600_HPP_
|
||||
|
||||
# include <boost/config.hpp>
|
||||
# include <boost/type_traits.hpp>
|
||||
# include <boost/iterator.hpp>
|
||||
# include <boost/type_traits/remove_const.hpp>
|
||||
# include <boost/type_traits/detail/yes_no_type.hpp>
|
||||
# include <boost/type_traits/is_pointer.hpp>
|
||||
# include <boost/type_traits/is_base_and_derived.hpp>
|
||||
# include <boost/mpl/if.hpp>
|
||||
# include <boost/mpl/aux_/has_xxx.hpp>
|
||||
# include <iterator>
|
||||
# include <cstddef>
|
||||
|
||||
# if defined(BOOST_MSVC_STD_ITERATOR)
|
||||
# include <xtree>
|
||||
# include <deque>
|
||||
# include <list>
|
||||
# if 0 && defined(__ICL) // Re-enable this to pick up the Intel fixes where they left off
|
||||
# include <iosfwd>
|
||||
# include <memory>
|
||||
# endif
|
||||
# endif
|
||||
|
||||
// should be the last #include
|
||||
#include "boost/type_traits/detail/bool_trait_def.hpp"
|
||||
|
||||
// STLPort 4.0 and betas have a bug when debugging is enabled and there is no
|
||||
// partial specialization: instead of an iterator_category typedef, the standard
|
||||
@ -80,9 +71,9 @@
|
||||
// Also, whether debugging is enabled or not, there is a broken specialization
|
||||
// of std::iterator<output_iterator_tag,void,void,void,void> which has no
|
||||
// typedefs but iterator_category.
|
||||
# if defined(__SGI_STL_PORT) && (__SGI_STL_PORT <= 0x410) && !defined(__STL_CLASS_PARTIAL_SPECIALIZATION)
|
||||
# if defined(__SGI_STL_PORT)
|
||||
|
||||
# ifdef __STL_DEBUG
|
||||
# if (__SGI_STL_PORT <= 0x410) && !defined(__STL_CLASS_PARTIAL_SPECIALIZATION) && defined(__STL_DEBUG)
|
||||
# define BOOST_BAD_CONTAINER_ITERATOR_CATEGORY_TYPEDEF
|
||||
# endif
|
||||
|
||||
@ -91,338 +82,345 @@
|
||||
# endif // STLPort <= 4.1b4 && no partial specialization
|
||||
|
||||
namespace boost { namespace detail {
|
||||
# if !defined(BOOST_NO_STD_ITERATOR_TRAITS) && !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_MSVC_STD_ITERATOR)
|
||||
using std::iterator_traits;
|
||||
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(value_type)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(reference)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(pointer)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(difference_type)
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(iterator_category)
|
||||
|
||||
# if !defined(BOOST_NO_STD_ITERATOR_TRAITS) \
|
||||
&& !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
|
||||
&& !defined(BOOST_MSVC_STD_ITERATOR)
|
||||
// Define a new template so it can be specialized
|
||||
template <class Iterator>
|
||||
struct iterator_traits
|
||||
: std::iterator_traits<Iterator>
|
||||
{};
|
||||
using std::distance;
|
||||
# elif !defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) \
|
||||
&& !defined(BOOST_MSVC_STD_ITERATOR)
|
||||
|
||||
// Rogue Wave Standard Library fools itself into thinking partial
|
||||
// specialization is missing on some platforms (e.g. Sun), so fails to
|
||||
// supply iterator_traits!
|
||||
template <class Iterator>
|
||||
struct iterator_traits
|
||||
{
|
||||
typedef typename Iterator::value_type value_type;
|
||||
typedef typename Iterator::reference reference;
|
||||
typedef typename Iterator::pointer pointer;
|
||||
typedef typename Iterator::difference_type difference_type;
|
||||
typedef typename Iterator::iterator_category iterator_category;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct iterator_traits<T*>
|
||||
{
|
||||
typedef T value_type;
|
||||
typedef T& reference;
|
||||
typedef T* pointer;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef std::random_access_iterator_tag iterator_category;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
struct iterator_traits<T const*>
|
||||
{
|
||||
typedef T value_type;
|
||||
typedef T const& reference;
|
||||
typedef T const* pointer;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef std::random_access_iterator_tag iterator_category;
|
||||
};
|
||||
|
||||
# else
|
||||
|
||||
namespace iterator_traits_ {
|
||||
// is_mutable_iterator --
|
||||
//
|
||||
// A metafunction returning true iff T is a mutable iterator type
|
||||
// with a nested value_type. Will only work portably with iterators
|
||||
// whose operator* returns a reference, but that seems to be OK for
|
||||
// the iterators supplied by Dinkumware. Some input iterators may
|
||||
// compile-time if they arrive here, and if the compiler is strict
|
||||
// about not taking the address of an rvalue.
|
||||
|
||||
// Workarounds for less-capable implementations
|
||||
template <bool is_ptr> struct iterator_traits_select;
|
||||
// This one detects ordinary mutable iterators - the result of
|
||||
// operator* is convertible to the value_type.
|
||||
template <class T>
|
||||
type_traits::yes_type is_mutable_iterator_helper(T const*, BOOST_DEDUCED_TYPENAME T::value_type*);
|
||||
|
||||
template <class T> struct undefined;
|
||||
template <> struct iterator_traits_select<true>
|
||||
// This one detects output iterators such as ostream_iterator which
|
||||
// return references to themselves.
|
||||
template <class T>
|
||||
type_traits::yes_type is_mutable_iterator_helper(T const*, T const*);
|
||||
|
||||
type_traits::no_type is_mutable_iterator_helper(...);
|
||||
|
||||
template <class T>
|
||||
struct is_mutable_iterator_impl
|
||||
{
|
||||
template <class Ptr>
|
||||
struct traits
|
||||
{
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
typedef std::random_access_iterator_tag iterator_category;
|
||||
typedef Ptr pointer;
|
||||
#ifdef BOOST_MSVC
|
||||
// Keeps MSVC happy under certain circumstances. It seems class template default
|
||||
// arguments are partly instantiated even when not used when the class template
|
||||
// is the return type of a function template.
|
||||
typedef undefined<void> value_type;
|
||||
typedef undefined<void> reference;
|
||||
#endif
|
||||
static T t;
|
||||
|
||||
BOOST_STATIC_CONSTANT(bool, value = sizeof(
|
||||
detail::is_mutable_iterator_helper((T*)0, &*t))
|
||||
== sizeof(type_traits::yes_type)
|
||||
);
|
||||
};
|
||||
|
||||
BOOST_TT_AUX_BOOL_TRAIT_DEF1(
|
||||
is_mutable_iterator,T,::boost::detail::is_mutable_iterator_impl<T>::value)
|
||||
|
||||
|
||||
// is_full_iterator_traits --
|
||||
//
|
||||
// A metafunction returning true iff T has all the requisite nested
|
||||
// types to satisfy the requirements for a fully-conforming
|
||||
// iterator_traits implementation.
|
||||
template <class T>
|
||||
struct is_full_iterator_traits_impl
|
||||
{
|
||||
enum { value =
|
||||
has_value_type<T>::value
|
||||
& has_reference<T>::value
|
||||
& has_pointer<T>::value
|
||||
& has_difference_type<T>::value
|
||||
& has_iterator_category<T>::value
|
||||
};
|
||||
};
|
||||
|
||||
BOOST_TT_AUX_BOOL_TRAIT_DEF1(
|
||||
is_full_iterator_traits,T,::boost::detail::is_full_iterator_traits_impl<T>::value)
|
||||
|
||||
typedef char yes_type;
|
||||
typedef double no_type;
|
||||
|
||||
# ifdef BOOST_BAD_CONTAINER_ITERATOR_CATEGORY_TYPEDEF
|
||||
|
||||
no_type bad_category_helper(...);
|
||||
template <class C, class T> yes_type bad_category_helper(std::_DBG_iter<C,T>*);
|
||||
|
||||
template <bool has_bad_category_typedef> struct bad_category_select;
|
||||
template <>
|
||||
struct bad_category_select<true>
|
||||
# ifdef BOOST_BAD_CONTAINER_ITERATOR_CATEGORY_TYPEDEF
|
||||
BOOST_MPL_HAS_XXX_TRAIT_DEF(_Iterator_category)
|
||||
|
||||
// is_stlport_40_debug_iterator --
|
||||
//
|
||||
// A metafunction returning true iff T has all the requisite nested
|
||||
// types to satisfy the requirements of an STLPort 4.0 debug iterator
|
||||
// iterator_traits implementation.
|
||||
template <class T>
|
||||
struct is_stlport_40_debug_iterator_impl
|
||||
{
|
||||
template <class Iterator>
|
||||
struct category { typedef typename Iterator::_Iterator_category type; };
|
||||
};
|
||||
template <>
|
||||
struct bad_category_select<false>
|
||||
{
|
||||
template <class Iterator>
|
||||
struct category { typedef typename Iterator::iterator_category type; };
|
||||
};
|
||||
|
||||
template <class Iterator>
|
||||
struct iterator_category_select
|
||||
{
|
||||
private:
|
||||
static Iterator p;
|
||||
enum { has_bad_category
|
||||
= sizeof(bad_category_helper(&p)) == sizeof(yes_type) };
|
||||
typedef bad_category_select<has_bad_category> category_select;
|
||||
public:
|
||||
typedef typename category_select::template category<Iterator>::type type;
|
||||
};
|
||||
|
||||
# endif
|
||||
|
||||
# ifdef BOOST_BAD_OUTPUT_ITERATOR_SPECIALIZATION
|
||||
template <bool is_bad_output_iterator> struct bad_output_iterator_select;
|
||||
template <>
|
||||
struct bad_output_iterator_select<true>
|
||||
{
|
||||
template <class Iterator>
|
||||
struct non_category_traits {
|
||||
typedef void value_type;
|
||||
typedef void difference_type;
|
||||
typedef void pointer;
|
||||
typedef void reference;
|
||||
enum { value =
|
||||
has_value_type<T>::value
|
||||
& has_reference<T>::value
|
||||
& has_pointer<T>::value
|
||||
& has_difference_type<T>::value
|
||||
& has__Iterator_category<T>::value
|
||||
};
|
||||
};
|
||||
template <>
|
||||
struct bad_output_iterator_select<false>
|
||||
{
|
||||
template <class Iterator>
|
||||
struct non_category_traits {
|
||||
typedef typename Iterator::value_type value_type;
|
||||
typedef typename Iterator::difference_type difference_type;
|
||||
typedef typename Iterator::pointer pointer;
|
||||
typedef typename Iterator::reference reference;
|
||||
};
|
||||
};
|
||||
# endif
|
||||
|
||||
# if defined(BOOST_MSVC_STD_ITERATOR)
|
||||
BOOST_TT_AUX_BOOL_TRAIT_DEF1(
|
||||
is_stlport_40_debug_iterator,T,::boost::detail::is_stlport_40_debug_iterator_impl<T>::value)
|
||||
|
||||
template <class T>
|
||||
struct stlport_40_debug_iterator_traits
|
||||
{
|
||||
typedef typename T::value_type value_type;
|
||||
typedef typename T::reference reference;
|
||||
typedef typename T::pointer pointer;
|
||||
typedef typename T::difference_type difference_type;
|
||||
typedef typename T::_Iterator_category iterator_category;
|
||||
};
|
||||
# endif // BOOST_BAD_CONTAINER_ITERATOR_CATEGORY_TYPEDEF
|
||||
|
||||
template <class T> struct pointer_iterator_traits;
|
||||
|
||||
# ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
template <class T>
|
||||
struct pointer_iterator_traits<T*>
|
||||
{
|
||||
typedef remove_const<T>::type value_type;
|
||||
typedef T* pointer;
|
||||
typedef T& reference;
|
||||
typedef std::random_access_iterator_tag iterator_category;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
};
|
||||
# else
|
||||
template <class Ptr>
|
||||
struct must_manually_specialize_boost_detail_iterator_traits;
|
||||
|
||||
template <class T>
|
||||
struct pointer_iterator_traits
|
||||
{
|
||||
typedef T pointer;
|
||||
typedef std::random_access_iterator_tag iterator_category;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
|
||||
// Makes MSVC6 happy under some circumstances
|
||||
typedef must_manually_specialize_boost_detail_iterator_traits<T> value_type;
|
||||
typedef must_manually_specialize_boost_detail_iterator_traits<T> reference;
|
||||
};
|
||||
|
||||
// Use this as a base class in manual iterator_traits specializations
|
||||
// for pointer types. T should be the value_type. CV should be the
|
||||
// cv-qualified value_type to which */& is added in order to produce
|
||||
// pointer/reference.
|
||||
template <class T, class CV = T>
|
||||
struct ptr_iter_traits
|
||||
{
|
||||
typedef T value_type;
|
||||
typedef CV* pointer;
|
||||
typedef CV& reference;
|
||||
typedef std::random_access_iterator_tag iterator_category;
|
||||
typedef std::ptrdiff_t difference_type;
|
||||
};
|
||||
# endif // BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
// We'll sort iterator types into one of these classifications, from which we
|
||||
// can determine the difference_type, pointer, reference, and value_type
|
||||
enum {
|
||||
not_msvc_stdlib_iterator,
|
||||
msvc_stdlib_const_iterator,
|
||||
msvc_stdlib_mutable_iterator,
|
||||
msvc_stdlib_ostream_iterator
|
||||
};
|
||||
|
||||
template <unsigned> struct msvc_traits_select;
|
||||
|
||||
template <> struct msvc_traits_select<not_msvc_stdlib_iterator>
|
||||
template <class Iterator>
|
||||
struct standard_iterator_traits
|
||||
{
|
||||
template <class Iterator>
|
||||
struct traits_ // calling this "traits" will confuse VC.
|
||||
{
|
||||
typedef typename Iterator::difference_type difference_type;
|
||||
typedef typename Iterator::value_type value_type;
|
||||
typedef typename Iterator::pointer pointer;
|
||||
typedef typename Iterator::reference reference;
|
||||
};
|
||||
typedef typename Iterator::difference_type difference_type;
|
||||
typedef typename Iterator::value_type value_type;
|
||||
typedef typename Iterator::pointer pointer;
|
||||
typedef typename Iterator::reference reference;
|
||||
typedef typename Iterator::iterator_category iterator_category;
|
||||
};
|
||||
|
||||
template <> struct msvc_traits_select<msvc_stdlib_mutable_iterator>
|
||||
template <class Iterator>
|
||||
struct msvc_stdlib_mutable_traits
|
||||
: std::iterator_traits<Iterator>
|
||||
{
|
||||
template <class Iterator>
|
||||
struct traits_
|
||||
{
|
||||
typedef typename Iterator::distance_type difference_type;
|
||||
typedef typename Iterator::value_type value_type;
|
||||
typedef value_type* pointer;
|
||||
typedef value_type& reference;
|
||||
};
|
||||
typedef typename std::iterator_traits<Iterator>::distance_type difference_type;
|
||||
typedef value_type* pointer;
|
||||
typedef value_type& reference;
|
||||
};
|
||||
|
||||
template <> struct msvc_traits_select<msvc_stdlib_const_iterator>
|
||||
template <class Iterator>
|
||||
struct msvc_stdlib_const_traits
|
||||
: std::iterator_traits<Iterator>
|
||||
{
|
||||
template <class Iterator>
|
||||
struct traits_
|
||||
{
|
||||
typedef typename Iterator::distance_type difference_type;
|
||||
typedef typename Iterator::value_type value_type;
|
||||
typedef const value_type* pointer;
|
||||
typedef const value_type& reference;
|
||||
};
|
||||
typedef typename std::iterator_traits<Iterator>::distance_type difference_type;
|
||||
typedef const value_type* pointer;
|
||||
typedef const value_type& reference;
|
||||
};
|
||||
|
||||
template <> struct msvc_traits_select<msvc_stdlib_ostream_iterator>
|
||||
# ifdef BOOST_BAD_OUTPUT_ITERATOR_SPECIALIZATION
|
||||
template <class Iterator>
|
||||
struct is_bad_output_iterator
|
||||
: is_base_and_derived<
|
||||
std::iterator<std::output_iterator_tag,void,void,void,void>
|
||||
, Iterator>
|
||||
{
|
||||
template <class Iterator>
|
||||
struct traits_
|
||||
{
|
||||
typedef typename Iterator::distance_type difference_type;
|
||||
typedef typename Iterator::value_type value_type;
|
||||
typedef void pointer;
|
||||
typedef void reference;
|
||||
};
|
||||
};
|
||||
|
||||
// These functions allow us to detect which classification a given iterator type
|
||||
// falls into.
|
||||
|
||||
// Is the iterator derived from std::iterator?
|
||||
no_type is_std_iterator_helper(...);
|
||||
template <class V, class D, class C>
|
||||
yes_type is_std_iterator_helper(const volatile std::iterator<V,D,C>*);
|
||||
|
||||
#if 0 && defined(__ICL) // re-enable this to pick up with the Intel C++ fixes where they left off
|
||||
// for some reason, it's unable to make the deduction of derivation :(
|
||||
template<class K, class Ty, class Kfn, class Pr, class A>
|
||||
yes_type is_std_iterator_helper(const volatile typename std::_Tree<K,Ty,Kfn,Pr,A>::iterator*);
|
||||
template<class Ty, class A>
|
||||
yes_type is_std_iterator_helper(const volatile typename std::list<Ty,A>::iterator*);
|
||||
template<class Ty, class A>
|
||||
yes_type is_std_iterator_helper(const volatile typename std::deque<Ty,A>::iterator*);
|
||||
|
||||
template<class K, class Ty, class Kfn, class Pr, class A>
|
||||
yes_type is_std_iterator_helper(const volatile typename std::_Tree<K,Ty,Kfn,Pr,A>::const_iterator*);
|
||||
template<class Ty, class A>
|
||||
yes_type is_std_iterator_helper(const volatile typename std::list<Ty,A>::const_iterator*);
|
||||
template<class Ty, class A>
|
||||
yes_type is_std_iterator_helper(const volatile typename std::deque<Ty,A>::const_iterator*);
|
||||
|
||||
template<class RI, class Ty, class Rt, class Pt, class D>
|
||||
yes_type is_std_iterator_helper(const volatile std::reverse_iterator<RI,Ty,Rt,Pt,D>*);
|
||||
template<class BI, class Ty, class Rt, class Pt, class D>
|
||||
yes_type is_std_iterator_helper(const volatile std::reverse_bidirectional_iterator<BI,Ty,Rt,Pt,D>*);
|
||||
template<class C>
|
||||
yes_type is_std_iterator_helper(const volatile std::back_insert_iterator<C>*);
|
||||
template<class C>
|
||||
yes_type is_std_iterator_helper(const volatile std::front_insert_iterator<C>*);
|
||||
template<class C>
|
||||
yes_type is_std_iterator_helper(const volatile std::insert_iterator<C>*);
|
||||
template<class U, class E, class Tr>
|
||||
yes_type is_std_iterator_helper(const volatile std::istream_iterator<U,E,Tr>*);
|
||||
template<class E, class Tr>
|
||||
yes_type is_std_iterator_helper(const volatile std::istreambuf_iterator<E,Tr>*);
|
||||
template<class E, class Tr>
|
||||
yes_type is_std_iterator_helper(const volatile std::ostreambuf_iterator<E,Tr>*);
|
||||
template<class Oi, class Ty>
|
||||
yes_type is_std_iterator_helper(const volatile std::raw_storage_iterator<Oi,Ty>*);
|
||||
#endif
|
||||
|
||||
// Is the iterator derived from boost::iterator?
|
||||
template <class C, class T, class D, class P, class R>
|
||||
yes_type is_boost_iterator_helper(const volatile boost::iterator<C,T,D,P,R>*);
|
||||
no_type is_boost_iterator_helper(...);
|
||||
|
||||
// Is the iterator one of the known mutable container iterators?
|
||||
template<class K, class Ty, class Kfn, class Pr, class A>
|
||||
yes_type is_mutable_iterator_helper(const volatile typename std::_Tree<K,Ty,Kfn,Pr,A>::iterator*);
|
||||
template<class Ty, class A>
|
||||
yes_type is_mutable_iterator_helper(const volatile typename std::list<Ty,A>::iterator*);
|
||||
template<class Ty, class A>
|
||||
yes_type is_mutable_iterator_helper(const volatile typename std::deque<Ty,A>::iterator*);
|
||||
no_type is_mutable_iterator_helper(...);
|
||||
|
||||
// Is the iterator an ostream_iterator?
|
||||
template<class T, class CharT, class Traits>
|
||||
yes_type is_ostream_iterator_helper(const volatile std::ostream_iterator<T,CharT,Traits>*);
|
||||
no_type is_ostream_iterator_helper(...);
|
||||
|
||||
#if 0 && defined(__ICL)
|
||||
// this static assertion highlights the first of a few problems getting this to
|
||||
// work with the Intel compiler. We can get past it with the many definitions
|
||||
// for is_std_iterator_helper above, but there are other failures.
|
||||
template <bool> struct check;
|
||||
template <> struct check<true> {};
|
||||
check<(sizeof(is_std_iterator_helper((std::istream_iterator<int>*)0)) == sizeof(yes_type))> assertion;
|
||||
#endif
|
||||
|
||||
template <class T>
|
||||
struct msvc_iterator_classification {
|
||||
BOOST_STATIC_CONSTANT(unsigned,
|
||||
value = (sizeof(is_ostream_iterator_helper((T*)0)) == sizeof(yes_type))
|
||||
? msvc_stdlib_ostream_iterator
|
||||
: (sizeof(is_mutable_iterator_helper((T*)0)) == sizeof(yes_type))
|
||||
? msvc_stdlib_mutable_iterator
|
||||
: (sizeof(is_std_iterator_helper((T*)0)) == sizeof(yes_type)
|
||||
&& sizeof(is_boost_iterator_helper((T*)0)) == sizeof(no_type))
|
||||
? msvc_stdlib_const_iterator
|
||||
: not_msvc_stdlib_iterator
|
||||
);
|
||||
struct bad_output_iterator_traits
|
||||
{
|
||||
typedef void value_type;
|
||||
typedef void difference_type;
|
||||
typedef std::output_iterator_tag iterator_category;
|
||||
typedef void pointer;
|
||||
typedef void reference;
|
||||
};
|
||||
# endif
|
||||
|
||||
template <> struct iterator_traits_select<false>
|
||||
// If we're looking at an MSVC6 (old Dinkumware) ``standard''
|
||||
// iterator, this will generate an appropriate traits class.
|
||||
template <class Iterator>
|
||||
struct msvc_stdlib_iterator_traits
|
||||
: mpl::if_<
|
||||
is_mutable_iterator<Iterator>
|
||||
, msvc_stdlib_mutable_traits<Iterator>
|
||||
, msvc_stdlib_const_traits<Iterator>
|
||||
>::type
|
||||
{};
|
||||
|
||||
template <class Iterator>
|
||||
struct non_pointer_iterator_traits
|
||||
: mpl::if_<
|
||||
// if the iterator contains all the right nested types...
|
||||
is_full_iterator_traits<Iterator>
|
||||
// Use a standard iterator_traits implementation
|
||||
, standard_iterator_traits<Iterator>
|
||||
# ifdef BOOST_BAD_CONTAINER_ITERATOR_CATEGORY_TYPEDEF
|
||||
// Check for STLPort 4.0 broken _Iterator_category type
|
||||
, mpl::if_<
|
||||
is_stlport_40_debug_iterator<Iterator>
|
||||
, stlport_40_debug_iterator_traits<Iterator>
|
||||
# endif
|
||||
// Otherwise, assume it's a Dinkum iterator
|
||||
, msvc_stdlib_iterator_traits<Iterator>
|
||||
# ifdef BOOST_BAD_CONTAINER_ITERATOR_CATEGORY_TYPEDEF
|
||||
>::type
|
||||
# endif
|
||||
>::type
|
||||
{
|
||||
template <class Iterator>
|
||||
struct traits
|
||||
{
|
||||
# if defined(BOOST_MSVC_STD_ITERATOR)
|
||||
typedef msvc_traits_select<(
|
||||
msvc_iterator_classification<Iterator>::value
|
||||
)>::template traits_<Iterator> inner_traits;
|
||||
|
||||
typedef typename inner_traits::difference_type difference_type;
|
||||
typedef typename inner_traits::value_type value_type;
|
||||
typedef typename inner_traits::pointer pointer;
|
||||
typedef typename inner_traits::reference reference;
|
||||
# elif !defined(BOOST_BAD_OUTPUT_ITERATOR_SPECIALIZATION)
|
||||
typedef typename Iterator::difference_type difference_type;
|
||||
typedef typename Iterator::value_type value_type;
|
||||
typedef typename Iterator::pointer pointer;
|
||||
typedef typename Iterator::reference reference;
|
||||
# else
|
||||
typedef bad_output_iterator_select<
|
||||
is_convertible<const volatile Iterator*,
|
||||
const volatile std::iterator<std::output_iterator_tag,void,void,void,void>*
|
||||
>::value> non_category_traits_select;
|
||||
typedef non_category_traits_select::template non_category_traits<Iterator> non_category_traits;
|
||||
public:
|
||||
typedef typename non_category_traits::value_type value_type;
|
||||
typedef typename non_category_traits::difference_type difference_type;
|
||||
typedef typename non_category_traits::pointer pointer;
|
||||
typedef typename non_category_traits::reference reference;
|
||||
# endif
|
||||
|
||||
# if !defined(BOOST_BAD_CONTAINER_ITERATOR_CATEGORY_TYPEDEF)
|
||||
typedef typename Iterator::iterator_category iterator_category;
|
||||
# else
|
||||
typedef typename iterator_category_select<Iterator>::type iterator_category;
|
||||
# endif
|
||||
};
|
||||
};
|
||||
|
||||
} // namespace boost::detail::iterator_traits_
|
||||
template <class Iterator>
|
||||
struct iterator_traits_aux
|
||||
: mpl::if_<
|
||||
is_pointer<Iterator>
|
||||
, pointer_iterator_traits<Iterator>
|
||||
, non_pointer_iterator_traits<Iterator>
|
||||
>::type
|
||||
{
|
||||
};
|
||||
|
||||
template <class Iterator>
|
||||
struct iterator_traits
|
||||
: iterator_traits_::iterator_traits_select<is_pointer<Iterator>::value>::template traits<Iterator>
|
||||
{
|
||||
// Explicit forwarding from base class needed to keep MSVC6 happy
|
||||
// under some circumstances.
|
||||
private:
|
||||
typedef typename iterator_traits_::iterator_traits_select<
|
||||
is_pointer<remove_cv<Iterator>::type>::value>::template traits<Iterator> traits;
|
||||
# ifdef BOOST_BAD_OUTPUT_ITERATOR_SPECIALIZATION
|
||||
typedef
|
||||
typename mpl::if_<
|
||||
is_bad_output_iterator<Iterator>
|
||||
, bad_output_iterator_traits
|
||||
, iterator_traits_aux<Iterator>
|
||||
>::type base;
|
||||
# else
|
||||
typedef iterator_traits_aux<Iterator> base;
|
||||
# endif
|
||||
public:
|
||||
// Why do I need to define these typedefs? It keeps MSVC happy somehow.
|
||||
// Why don't I need to define the other typedefs? Who knows?!?
|
||||
typedef typename traits::difference_type difference_type;
|
||||
typedef typename traits::iterator_category iterator_category;
|
||||
typedef typename base::value_type value_type;
|
||||
typedef typename base::pointer pointer;
|
||||
typedef typename base::reference reference;
|
||||
typedef typename base::difference_type difference_type;
|
||||
typedef typename base::iterator_category iterator_category;
|
||||
};
|
||||
|
||||
namespace iterator_traits_ {
|
||||
// This specialization cuts off ETI (Early Template Instantiation) for MSVC.
|
||||
template <> struct iterator_traits<int>{};
|
||||
|
||||
template <class Category>
|
||||
struct distance_select {
|
||||
template <class Iterator>
|
||||
static typename ::boost::detail::iterator_traits<Iterator>::difference_type
|
||||
distance(Iterator i1, const Iterator i2)
|
||||
{
|
||||
typename ::boost::detail::iterator_traits<Iterator>::difference_type result = 0;
|
||||
while (i1 != i2)
|
||||
{
|
||||
++i1;
|
||||
++result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
|
||||
template <>
|
||||
struct distance_select<std::random_access_iterator_tag> {
|
||||
template <class Iterator>
|
||||
static typename ::boost::detail::iterator_traits<Iterator>::difference_type
|
||||
distance(const Iterator i1, const Iterator i2)
|
||||
{
|
||||
return i2 - i1;
|
||||
}
|
||||
};
|
||||
namespace iterator_traits_
|
||||
{
|
||||
template <class Iterator, class Difference>
|
||||
struct distance_select
|
||||
{
|
||||
static Difference execute(Iterator i1, const Iterator i2, ...)
|
||||
{
|
||||
typename Difference result = 0;
|
||||
while (i1 != i2)
|
||||
{
|
||||
++i1;
|
||||
++result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static Difference execute(Iterator i1, const Iterator i2, std::random_access_iterator_tag*)
|
||||
{
|
||||
return i2 - i1;
|
||||
}
|
||||
};
|
||||
} // namespace boost::detail::iterator_traits_
|
||||
|
||||
template <class Iterator>
|
||||
inline typename ::boost::detail::iterator_traits<Iterator>::difference_type
|
||||
distance(const Iterator& first, const Iterator& last)
|
||||
inline typename iterator_traits<Iterator>::difference_type
|
||||
distance(Iterator first, Iterator last)
|
||||
{
|
||||
typedef typename iterator_traits<Iterator>::difference_type diff_t;
|
||||
typedef typename ::boost::detail::iterator_traits<Iterator>::iterator_category iterator_category;
|
||||
return iterator_traits_::distance_select<iterator_category>::distance(first, last);
|
||||
|
||||
return iterator_traits_::distance_select<Iterator,diff_t>::execute(
|
||||
first, last, (iterator_category*)0);
|
||||
}
|
||||
# endif // workarounds
|
||||
|
||||
|
74
include/boost/detail/lightweight_test.hpp
Normal file
74
include/boost/detail/lightweight_test.hpp
Normal file
@ -0,0 +1,74 @@
|
||||
#ifndef BOOST_DETAIL_LIGHTWEIGHT_TEST_HPP_INCLUDED
|
||||
#define BOOST_DETAIL_LIGHTWEIGHT_TEST_HPP_INCLUDED
|
||||
|
||||
#if _MSC_VER >= 1020
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// boost/detail/lightweight_test.hpp - lightweight test library
|
||||
//
|
||||
// Copyright (c) 2002 Peter Dimov and Multi Media Ltd.
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
// BOOST_TEST(expression)
|
||||
// BOOST_ERROR(message)
|
||||
//
|
||||
// int boost::report_errors()
|
||||
//
|
||||
|
||||
#include <boost/current_function.hpp>
|
||||
#include <iostream>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
inline int & test_errors()
|
||||
{
|
||||
static int x = 0;
|
||||
return x;
|
||||
}
|
||||
|
||||
inline void test_failed_impl(char const * expr, char const * file, int line, char const * function)
|
||||
{
|
||||
std::cerr << file << "(" << line << "): test '" << expr << "' failed in function '" << function << "'" << std::endl;
|
||||
++test_errors();
|
||||
}
|
||||
|
||||
inline void error_impl(char const * msg, char const * file, int line, char const * function)
|
||||
{
|
||||
std::cerr << file << "(" << line << "): " << msg << " in function '" << function << "'" << std::endl;
|
||||
++test_errors();
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
inline int report_errors()
|
||||
{
|
||||
int errors = detail::test_errors();
|
||||
|
||||
if(errors == 0)
|
||||
{
|
||||
std::cerr << "No errors detected." << std::endl;
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
std::cerr << errors << " error" << (errors == 1? "": "s") << " detected." << std::endl;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#define BOOST_TEST(expr) ((expr)? (void)0: ::boost::detail::test_failed_impl(#expr, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION))
|
||||
#define BOOST_ERROR(msg) ::boost::detail::error_impl(msg, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION)
|
||||
|
||||
#endif // #ifndef BOOST_DETAIL_LIGHTWEIGHT_TEST_HPP_INCLUDED
|
@ -4,6 +4,11 @@
|
||||
// "as is" without express or implied warranty, and with no claim as
|
||||
// to its suitability for any purpose.
|
||||
|
||||
// Revision History:
|
||||
|
||||
// 04 Oct 2001 David Abrahams
|
||||
// Changed name of "bind" to "select" to avoid problems with MSVC.
|
||||
|
||||
#ifndef BOOST_DETAIL_NAMED_TEMPLATE_PARAMS_HPP
|
||||
#define BOOST_DETAIL_NAMED_TEMPLATE_PARAMS_HPP
|
||||
|
||||
@ -20,7 +25,7 @@ namespace boost {
|
||||
|
||||
struct dummy_default_gen {
|
||||
template <class Base, class Traits>
|
||||
struct bind {
|
||||
struct select {
|
||||
typedef default_argument type;
|
||||
};
|
||||
};
|
||||
@ -41,14 +46,14 @@ namespace boost {
|
||||
|
||||
struct choose_default {
|
||||
template <class Arg, class DefaultGen, class Base, class Traits>
|
||||
struct bind {
|
||||
struct select {
|
||||
typedef typename default_generator<DefaultGen>::type Gen;
|
||||
typedef typename Gen::template bind<Base,Traits>::type type;
|
||||
typedef typename Gen::template select<Base,Traits>::type type;
|
||||
};
|
||||
};
|
||||
struct choose_arg {
|
||||
template <class Arg, class DefaultGen, class Base, class Traits>
|
||||
struct bind {
|
||||
struct select {
|
||||
typedef Arg type;
|
||||
};
|
||||
};
|
||||
@ -81,7 +86,7 @@ namespace boost {
|
||||
#endif
|
||||
public:
|
||||
typedef typename Selector
|
||||
::template bind<Arg, DefaultGen, Base, Traits>::type type;
|
||||
::template select<Arg, DefaultGen, Base, Traits>::type type;
|
||||
};
|
||||
|
||||
// To differentiate an unnamed parameter from a traits generator
|
||||
@ -94,36 +99,38 @@ namespace boost {
|
||||
};
|
||||
|
||||
struct choose_named_params {
|
||||
template <class Prev> struct bind { typedef Prev type; };
|
||||
template <class Prev> struct select { typedef Prev type; };
|
||||
};
|
||||
struct choose_default_arg {
|
||||
template <class Prev> struct bind {
|
||||
template <class Prev> struct select {
|
||||
typedef detail::default_argument type;
|
||||
};
|
||||
};
|
||||
|
||||
template <bool Named> struct choose_default_dispatch { };
|
||||
template <> struct choose_default_dispatch<true> {
|
||||
template <bool Named> struct choose_default_dispatch_;
|
||||
template <> struct choose_default_dispatch_<true> {
|
||||
typedef choose_named_params type;
|
||||
};
|
||||
template <> struct choose_default_dispatch<false> {
|
||||
template <> struct choose_default_dispatch_<false> {
|
||||
typedef choose_default_arg type;
|
||||
};
|
||||
|
||||
// The use of inheritance here is a Solaris Forte 6 workaround.
|
||||
template <bool Named> struct choose_default_dispatch
|
||||
: public choose_default_dispatch_<Named> { };
|
||||
|
||||
template <class PreviousArg>
|
||||
struct choose_default_argument {
|
||||
enum { is_named = is_named_param_list<PreviousArg>::value };
|
||||
typedef typename choose_default_dispatch<is_named>::type Selector;
|
||||
typedef typename Selector::template bind<PreviousArg>::type type;
|
||||
typedef typename Selector::template select<PreviousArg>::type type;
|
||||
};
|
||||
|
||||
// This macro assumes that there is a class named default_##TYPE
|
||||
// defined before the application of the macro. This class should
|
||||
// have a single member class template named "bind" with two
|
||||
// have a single member class template named "select" with two
|
||||
// template parameters: the type of the class being created (e.g.,
|
||||
// the iterator_adaptor type when creating iterator adaptors) and
|
||||
// a traits class. The bind class should have a single typedef
|
||||
// a traits class. The select class should have a single typedef
|
||||
// named "type" that produces the default for TYPE. See
|
||||
// boost/iterator_adaptors.hpp for an example usage. Also,
|
||||
// applications of this macro must be placed in namespace
|
||||
@ -132,7 +139,7 @@ namespace boost {
|
||||
#define BOOST_NAMED_TEMPLATE_PARAM(TYPE) \
|
||||
struct get_##TYPE##_from_named { \
|
||||
template <class Base, class NamedParams, class Traits> \
|
||||
struct bind { \
|
||||
struct select { \
|
||||
typedef typename NamedParams::traits NamedTraits; \
|
||||
typedef typename NamedTraits::TYPE TYPE; \
|
||||
typedef typename resolve_default<TYPE, \
|
||||
@ -140,7 +147,7 @@ namespace boost {
|
||||
}; \
|
||||
}; \
|
||||
struct pass_thru_##TYPE { \
|
||||
template <class Base, class Arg, class Traits> struct bind { \
|
||||
template <class Base, class Arg, class Traits> struct select { \
|
||||
typedef typename resolve_default<Arg, \
|
||||
default_##TYPE, Base, Traits>::type type; \
|
||||
};\
|
||||
@ -158,7 +165,7 @@ namespace boost {
|
||||
enum { is_named = is_named_param_list<X>::value }; \
|
||||
typedef typename get_##TYPE##_dispatch<is_named>::type Selector; \
|
||||
public: \
|
||||
typedef typename Selector::template bind<Base, X, Traits>::type type; \
|
||||
typedef typename Selector::template select<Base, X, Traits>::type type; \
|
||||
}; \
|
||||
template <> struct default_generator<default_##TYPE> { \
|
||||
typedef default_##TYPE type; \
|
||||
|
@ -70,9 +70,7 @@
|
||||
# include <boost/static_assert.hpp>
|
||||
# include <boost/type_traits.hpp>
|
||||
# include <boost/detail/select_type.hpp>
|
||||
# ifndef BOOST_NO_LIMITS
|
||||
# include <limits>
|
||||
# endif
|
||||
# include <boost/limits.hpp>
|
||||
|
||||
namespace boost { namespace detail {
|
||||
|
||||
@ -83,7 +81,7 @@ namespace boost { namespace detail {
|
||||
template <class Number>
|
||||
struct is_signed
|
||||
{
|
||||
#if defined(BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS) || defined(BOOST_MSVC)
|
||||
#if defined(BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS) || defined(BOOST_MSVC) && BOOST_MSVC <= 1300
|
||||
BOOST_STATIC_CONSTANT(bool, value = (Number(-1) < Number(0)));
|
||||
#else
|
||||
BOOST_STATIC_CONSTANT(bool, value = std::numeric_limits<Number>::is_signed);
|
||||
@ -137,7 +135,7 @@ namespace boost { namespace detail {
|
||||
private:
|
||||
typedef Integer integer_type;
|
||||
typedef std::numeric_limits<integer_type> x;
|
||||
# ifdef BOOST_MSVC
|
||||
# if defined(BOOST_MSVC) && BOOST_MSVC <= 1300
|
||||
// for some reason, MSVC asserts when it shouldn't unless we make these
|
||||
// local definitions
|
||||
BOOST_STATIC_CONSTANT(bool, is_integer = x::is_integer);
|
||||
|
187
include/boost/detail/quick_allocator.hpp
Normal file
187
include/boost/detail/quick_allocator.hpp
Normal file
@ -0,0 +1,187 @@
|
||||
#ifndef BOOST_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED
|
||||
#define BOOST_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED
|
||||
|
||||
#if _MSC_VER >= 1020
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
//
|
||||
// detail/quick_allocator.hpp
|
||||
//
|
||||
// Copyright (c) 2003 David Abrahams
|
||||
// Copyright (c) 2003 Peter Dimov
|
||||
//
|
||||
// Permission to copy, use, modify, sell and distribute this software
|
||||
// is granted provided this copyright notice appears in all copies.
|
||||
// This software is provided "as is" without express or implied
|
||||
// warranty, and with no claim as to its suitability for any purpose.
|
||||
//
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
#include <boost/detail/lightweight_mutex.hpp>
|
||||
#include <boost/type_traits/type_with_alignment.hpp>
|
||||
#include <boost/type_traits/alignment_of.hpp>
|
||||
|
||||
#include <new> // ::operator new, ::operator delete
|
||||
#include <cstddef> // std::size_t
|
||||
|
||||
namespace boost
|
||||
{
|
||||
|
||||
namespace detail
|
||||
{
|
||||
|
||||
template<unsigned size, unsigned align_> union freeblock
|
||||
{
|
||||
typedef typename boost::type_with_alignment<align_>::type aligner_type;
|
||||
aligner_type aligner;
|
||||
char bytes[size];
|
||||
freeblock * next;
|
||||
};
|
||||
|
||||
template<unsigned size, unsigned align_> struct allocator_impl
|
||||
{
|
||||
typedef freeblock<size, align_> block;
|
||||
|
||||
// It may seem odd to use such small pages.
|
||||
//
|
||||
// However, on a typical Windows implementation that uses
|
||||
// the OS allocator, "normal size" pages interact with the
|
||||
// "ordinary" operator new, slowing it down dramatically.
|
||||
//
|
||||
// 512 byte pages are handled by the small object allocator,
|
||||
// and don't interfere with ::new.
|
||||
//
|
||||
// The other alternative is to use much bigger pages (1M.)
|
||||
//
|
||||
// It is surprisingly easy to hit pathological behavior by
|
||||
// varying the page size. g++ 2.96 on Red Hat Linux 7.2,
|
||||
// for example, passionately dislikes 496. 512 seems OK.
|
||||
|
||||
#if defined(BOOST_QA_PAGE_SIZE)
|
||||
|
||||
enum { items_per_page = BOOST_QA_PAGE_SIZE / size };
|
||||
|
||||
#else
|
||||
|
||||
enum { items_per_page = 512 / size }; // 1048560 / size
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef BOOST_HAS_THREADS
|
||||
static lightweight_mutex mutex;
|
||||
#endif
|
||||
|
||||
static block * free;
|
||||
static block * page;
|
||||
static unsigned last;
|
||||
|
||||
static inline void * alloc()
|
||||
{
|
||||
#ifdef BOOST_HAS_THREADS
|
||||
lightweight_mutex::scoped_lock lock(mutex);
|
||||
#endif
|
||||
if(block * x = free)
|
||||
{
|
||||
free = x->next;
|
||||
return x;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(last == items_per_page)
|
||||
{
|
||||
// "Listen to me carefully: there is no memory leak"
|
||||
// -- Scott Meyers, Eff C++ 2nd Ed Item 10
|
||||
page = ::new block[items_per_page];
|
||||
last = 0;
|
||||
}
|
||||
|
||||
return &page[last++];
|
||||
}
|
||||
}
|
||||
|
||||
static inline void * alloc(std::size_t n)
|
||||
{
|
||||
if(n != size) // class-specific new called for a derived object
|
||||
{
|
||||
return ::operator new(n);
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef BOOST_HAS_THREADS
|
||||
lightweight_mutex::scoped_lock lock(mutex);
|
||||
#endif
|
||||
if(block * x = free)
|
||||
{
|
||||
free = x->next;
|
||||
return x;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(last == items_per_page)
|
||||
{
|
||||
page = ::new block[items_per_page];
|
||||
last = 0;
|
||||
}
|
||||
|
||||
return &page[last++];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline void dealloc(void * pv)
|
||||
{
|
||||
if(pv != 0) // 18.4.1.1/13
|
||||
{
|
||||
#ifdef BOOST_HAS_THREADS
|
||||
lightweight_mutex::scoped_lock lock(mutex);
|
||||
#endif
|
||||
block * pb = static_cast<block *>(pv);
|
||||
pb->next = free;
|
||||
free = pb;
|
||||
}
|
||||
}
|
||||
|
||||
static inline void dealloc(void * pv, std::size_t n)
|
||||
{
|
||||
if(n != size) // class-specific delete called for a derived object
|
||||
{
|
||||
::operator delete(pv);
|
||||
}
|
||||
else if(pv != 0) // 18.4.1.1/13
|
||||
{
|
||||
#ifdef BOOST_HAS_THREADS
|
||||
lightweight_mutex::scoped_lock lock(mutex);
|
||||
#endif
|
||||
block * pb = static_cast<block *>(pv);
|
||||
pb->next = free;
|
||||
free = pb;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
#ifdef BOOST_HAS_THREADS
|
||||
template<unsigned size, unsigned align_>
|
||||
lightweight_mutex allocator_impl<size, align_>::mutex;
|
||||
#endif
|
||||
|
||||
template<unsigned size, unsigned align_>
|
||||
freeblock<size, align_> * allocator_impl<size, align_>::free = 0;
|
||||
|
||||
template<unsigned size, unsigned align_>
|
||||
freeblock<size, align_> * allocator_impl<size, align_>::page = 0;
|
||||
|
||||
template<unsigned size, unsigned align_>
|
||||
unsigned allocator_impl<size, align_>::last = allocator_impl<size, align_>::items_per_page;
|
||||
|
||||
template<class T>
|
||||
struct quick_allocator: public allocator_impl< sizeof(T), boost::alignment_of<T>::value >
|
||||
{
|
||||
};
|
||||
|
||||
} // namespace detail
|
||||
|
||||
} // namespace boost
|
||||
|
||||
#endif // #ifndef BOOST_DETAIL_QUICK_ALLOCATOR_HPP_INCLUDED
|
@ -36,12 +36,23 @@ namespace boost {
|
||||
|
||||
#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
|
||||
|
||||
template <int cond, class A, class B>
|
||||
// agurt, 15/sep/02: in certain cases Borland has problems with
|
||||
// choosing the right 'ct_if' specialization even though 'cond'
|
||||
// _does_ equal '1'; the easiest way to fix it is to make first
|
||||
// 'ct_if' non-type template parameter boolean.
|
||||
#if !defined(__BORLANDC__)
|
||||
template <bool cond, class A, class B>
|
||||
struct ct_if { typedef ct_if_error type; };
|
||||
template <class A, class B>
|
||||
struct ct_if<1, A, B> { typedef A type; };
|
||||
struct ct_if<true, A, B> { typedef A type; };
|
||||
template <class A, class B>
|
||||
struct ct_if<0, A, B> { typedef B type; };
|
||||
struct ct_if<false, A, B> { typedef B type; };
|
||||
#else
|
||||
template <bool cond, class A, class B>
|
||||
struct ct_if { typedef A type; };
|
||||
template <class A, class B>
|
||||
struct ct_if<false, A, B> { typedef B type; };
|
||||
#endif
|
||||
|
||||
template <class cond, class A, class B>
|
||||
struct ct_if_t { typedef ct_if_error type; };
|
||||
|
35
include/boost/visit_each.hpp
Normal file
35
include/boost/visit_each.hpp
Normal file
@ -0,0 +1,35 @@
|
||||
// Boost.Signals library
|
||||
//
|
||||
// Copyright (C) 2001 Doug Gregor (gregod@cs.rpi.edu)
|
||||
//
|
||||
// Permission to copy, use, sell and distribute this software is granted
|
||||
// provided this copyright notice appears in all copies.
|
||||
// Permission to modify the code and to distribute modified code is granted
|
||||
// provided this copyright notice appears in all copies, and a notice
|
||||
// that the code was modified is included with the copyright notice.
|
||||
//
|
||||
// This software is provided "as is" without express or implied warranty,
|
||||
// and with no claim as to its suitability for any purpose.
|
||||
|
||||
// For more information, see http://www.boost.org/libs/signals
|
||||
|
||||
#ifndef BOOST_VISIT_EACH_HPP
|
||||
#define BOOST_VISIT_EACH_HPP
|
||||
|
||||
#include <boost/config.hpp>
|
||||
|
||||
namespace boost {
|
||||
template<typename Visitor, typename T>
|
||||
inline void visit_each(Visitor& visitor, const T& t, long)
|
||||
{
|
||||
visitor(t);
|
||||
}
|
||||
|
||||
template<typename Visitor, typename T>
|
||||
inline void visit_each(Visitor& visitor, const T& t)
|
||||
{
|
||||
visit_each(visitor, t, 0);
|
||||
}
|
||||
}
|
||||
|
||||
#endif // BOOST_VISIT_EACH_HPP
|
Reference in New Issue
Block a user