Updating to Boost 1.55

This commit is contained in:
Strahinja Val Markovic 2014-03-01 11:00:20 -08:00
parent 992769cc2e
commit fa1d628943
292 changed files with 17335 additions and 9577 deletions

View File

@ -12,7 +12,7 @@
#define BOOST_STRING_CONCEPT_HPP #define BOOST_STRING_CONCEPT_HPP
#include <boost/concept_check.hpp> #include <boost/concept_check.hpp>
#include <boost/range/iterator_range.hpp> #include <boost/range/iterator_range_core.hpp>
#include <boost/range/begin.hpp> #include <boost/range/begin.hpp>
#include <boost/range/end.hpp> #include <boost/range/end.hpp>

View File

@ -12,7 +12,7 @@
#define BOOST_STRING_FIND_FORMAT_DETAIL_HPP #define BOOST_STRING_FIND_FORMAT_DETAIL_HPP
#include <boost/algorithm/string/config.hpp> #include <boost/algorithm/string/config.hpp>
#include <boost/range/iterator_range.hpp> #include <boost/range/iterator_range_core.hpp>
#include <boost/range/const_iterator.hpp> #include <boost/range/const_iterator.hpp>
#include <boost/range/iterator.hpp> #include <boost/range/iterator.hpp>
#include <boost/algorithm/string/detail/find_format_store.hpp> #include <boost/algorithm/string/detail/find_format_store.hpp>

View File

@ -12,7 +12,7 @@
#define BOOST_STRING_FIND_FORMAT_ALL_DETAIL_HPP #define BOOST_STRING_FIND_FORMAT_ALL_DETAIL_HPP
#include <boost/algorithm/string/config.hpp> #include <boost/algorithm/string/config.hpp>
#include <boost/range/iterator_range.hpp> #include <boost/range/iterator_range_core.hpp>
#include <boost/range/const_iterator.hpp> #include <boost/range/const_iterator.hpp>
#include <boost/range/value_type.hpp> #include <boost/range/value_type.hpp>
#include <boost/algorithm/string/detail/find_format_store.hpp> #include <boost/algorithm/string/detail/find_format_store.hpp>

View File

@ -12,7 +12,7 @@
#define BOOST_STRING_FIND_FORMAT_STORE_DETAIL_HPP #define BOOST_STRING_FIND_FORMAT_STORE_DETAIL_HPP
#include <boost/algorithm/string/config.hpp> #include <boost/algorithm/string/config.hpp>
#include <boost/range/iterator_range.hpp> #include <boost/range/iterator_range_core.hpp>
namespace boost { namespace boost {
namespace algorithm { namespace algorithm {

View File

@ -12,7 +12,7 @@
#define BOOST_STRING_FIND_ITERATOR_DETAIL_HPP #define BOOST_STRING_FIND_ITERATOR_DETAIL_HPP
#include <boost/algorithm/string/config.hpp> #include <boost/algorithm/string/config.hpp>
#include <boost/range/iterator_range.hpp> #include <boost/range/iterator_range_core.hpp>
#include <boost/iterator/iterator_facade.hpp> #include <boost/iterator/iterator_facade.hpp>
#include <boost/iterator/iterator_categories.hpp> #include <boost/iterator/iterator_categories.hpp>
#include <boost/function.hpp> #include <boost/function.hpp>

View File

@ -15,7 +15,7 @@
#include <boost/algorithm/string/constants.hpp> #include <boost/algorithm/string/constants.hpp>
#include <boost/detail/iterator.hpp> #include <boost/detail/iterator.hpp>
#include <boost/range/iterator_range.hpp> #include <boost/range/iterator_range_core.hpp>
#include <boost/range/begin.hpp> #include <boost/range/begin.hpp>
#include <boost/range/end.hpp> #include <boost/range/end.hpp>
#include <boost/range/empty.hpp> #include <boost/range/empty.hpp>
@ -142,7 +142,6 @@ namespace boost {
ForwardIteratorT End, ForwardIteratorT End,
std::forward_iterator_tag ) const std::forward_iterator_tag ) const
{ {
typedef ForwardIteratorT input_iterator_type;
typedef iterator_range<ForwardIteratorT> result_type; typedef iterator_range<ForwardIteratorT> result_type;
first_finder_type first_finder( first_finder_type first_finder(
@ -263,7 +262,6 @@ namespace boost {
ForwardIteratorT End, ForwardIteratorT End,
unsigned int N) const unsigned int N) const
{ {
typedef ForwardIteratorT input_iterator_type;
typedef iterator_range<ForwardIteratorT> result_type; typedef iterator_range<ForwardIteratorT> result_type;
// Sanity check // Sanity check
@ -298,7 +296,6 @@ namespace boost {
ForwardIteratorT End, ForwardIteratorT End,
unsigned int N) const unsigned int N) const
{ {
typedef ForwardIteratorT input_iterator_type;
typedef iterator_range<ForwardIteratorT> result_type; typedef iterator_range<ForwardIteratorT> result_type;
// Sanity check // Sanity check
@ -362,7 +359,6 @@ namespace boost {
unsigned int N, unsigned int N,
std::random_access_iterator_tag ) std::random_access_iterator_tag )
{ {
typedef ForwardIteratorT input_iterator_type;
typedef iterator_range<ForwardIteratorT> result_type; typedef iterator_range<ForwardIteratorT> result_type;
if ( (End<=Begin) || ( static_cast<unsigned int>(End-Begin) < N ) ) if ( (End<=Begin) || ( static_cast<unsigned int>(End-Begin) < N ) )
@ -436,7 +432,6 @@ namespace boost {
unsigned int N, unsigned int N,
std::random_access_iterator_tag ) std::random_access_iterator_tag )
{ {
typedef ForwardIteratorT input_iterator_type;
typedef iterator_range<ForwardIteratorT> result_type; typedef iterator_range<ForwardIteratorT> result_type;
if ( (End<=Begin) || ( static_cast<unsigned int>(End-Begin) < N ) ) if ( (End<=Begin) || ( static_cast<unsigned int>(End-Begin) < N ) )

View File

@ -14,7 +14,7 @@
#include <boost/algorithm/string/config.hpp> #include <boost/algorithm/string/config.hpp>
#include <boost/regex.hpp> #include <boost/regex.hpp>
#include <boost/range/iterator_range.hpp> #include <boost/range/iterator_range_core.hpp>
#include <boost/range/begin.hpp> #include <boost/range/begin.hpp>
#include <boost/range/end.hpp> #include <boost/range/end.hpp>

View File

@ -12,7 +12,7 @@
#define BOOST_STRING_FORMATTER_DETAIL_HPP #define BOOST_STRING_FORMATTER_DETAIL_HPP
#include <boost/range/iterator_range.hpp> #include <boost/range/iterator_range_core.hpp>
#include <boost/range/begin.hpp> #include <boost/range/begin.hpp>
#include <boost/range/end.hpp> #include <boost/range/end.hpp>
#include <boost/range/const_iterator.hpp> #include <boost/range/const_iterator.hpp>

View File

@ -13,7 +13,7 @@
#include <boost/algorithm/string/config.hpp> #include <boost/algorithm/string/config.hpp>
#include <functional> #include <functional>
#include <boost/range/iterator_range.hpp> #include <boost/range/iterator_range_core.hpp>
namespace boost { namespace boost {
namespace algorithm { namespace algorithm {

View File

@ -13,7 +13,7 @@
#include <boost/algorithm/string/config.hpp> #include <boost/algorithm/string/config.hpp>
#include <boost/range/iterator_range.hpp> #include <boost/range/iterator_range_core.hpp>
#include <boost/range/begin.hpp> #include <boost/range/begin.hpp>
#include <boost/range/end.hpp> #include <boost/range/end.hpp>
#include <boost/range/iterator.hpp> #include <boost/range/iterator.hpp>

View File

@ -13,7 +13,7 @@
#include <boost/algorithm/string/config.hpp> #include <boost/algorithm/string/config.hpp>
#include <boost/range/iterator_range.hpp> #include <boost/range/iterator_range_core.hpp>
#include <boost/range/begin.hpp> #include <boost/range/begin.hpp>
#include <boost/range/end.hpp> #include <boost/range/end.hpp>
#include <boost/range/iterator.hpp> #include <boost/range/iterator.hpp>

View File

@ -13,7 +13,7 @@
#include <deque> #include <deque>
#include <boost/detail/iterator.hpp> #include <boost/detail/iterator.hpp>
#include <boost/range/iterator_range.hpp> #include <boost/range/iterator_range_core.hpp>
#include <boost/range/begin.hpp> #include <boost/range/begin.hpp>
#include <boost/range/end.hpp> #include <boost/range/end.hpp>
#include <boost/range/const_iterator.hpp> #include <boost/range/const_iterator.hpp>

View File

@ -15,7 +15,7 @@
#include <boost/iterator/iterator_facade.hpp> #include <boost/iterator/iterator_facade.hpp>
#include <boost/iterator/iterator_categories.hpp> #include <boost/iterator/iterator_categories.hpp>
#include <boost/range/iterator_range.hpp> #include <boost/range/iterator_range_core.hpp>
#include <boost/range/begin.hpp> #include <boost/range/begin.hpp>
#include <boost/range/end.hpp> #include <boost/range/end.hpp>
#include <boost/range/iterator.hpp> #include <boost/range/iterator.hpp>
@ -132,12 +132,7 @@ namespace boost {
// increment // increment
void increment() void increment()
{ {
if(m_Match.begin() == m_Match.end())
m_Match=this->do_find(m_Match.end(),m_End); m_Match=this->do_find(m_Match.end(),m_End);
else {
input_iterator_type last = m_Match.begin();
m_Match=this->do_find(++last,m_End);
}
} }
// comparison // comparison

View File

@ -13,7 +13,7 @@
#include <boost/algorithm/string/config.hpp> #include <boost/algorithm/string/config.hpp>
#include <boost/range/iterator_range.hpp> #include <boost/range/iterator_range_core.hpp>
#include <boost/range/begin.hpp> #include <boost/range/begin.hpp>
#include <boost/range/end.hpp> #include <boost/range/end.hpp>
#include <boost/range/iterator.hpp> #include <boost/range/iterator.hpp>

View File

@ -13,7 +13,7 @@
#include <boost/detail/iterator.hpp> #include <boost/detail/iterator.hpp>
#include <boost/range/value_type.hpp> #include <boost/range/value_type.hpp>
#include <boost/range/iterator_range.hpp> #include <boost/range/iterator_range_core.hpp>
#include <boost/range/as_literal.hpp> #include <boost/range/as_literal.hpp>
#include <boost/algorithm/string/detail/formatter.hpp> #include <boost/algorithm/string/detail/formatter.hpp>

View File

@ -16,7 +16,7 @@
#include <iterator> #include <iterator>
#include <boost/iterator/transform_iterator.hpp> #include <boost/iterator/transform_iterator.hpp>
#include <boost/range/iterator_range.hpp> #include <boost/range/iterator_range_core.hpp>
#include <boost/range/begin.hpp> #include <boost/range/begin.hpp>
#include <boost/range/end.hpp> #include <boost/range/end.hpp>
#include <boost/range/iterator.hpp> #include <boost/range/iterator.hpp>

View File

@ -17,7 +17,7 @@
#include <boost/range/iterator.hpp> #include <boost/range/iterator.hpp>
#include <boost/range/const_iterator.hpp> #include <boost/range/const_iterator.hpp>
#include <boost/range/as_literal.hpp> #include <boost/range/as_literal.hpp>
#include <boost/range/iterator_range.hpp> #include <boost/range/iterator_range_core.hpp>
#include <boost/algorithm/string/compare.hpp> #include <boost/algorithm/string/compare.hpp>
#include <boost/algorithm/string/find.hpp> #include <boost/algorithm/string/find.hpp>

View File

@ -14,7 +14,7 @@
#include <boost/algorithm/string/config.hpp> #include <boost/algorithm/string/config.hpp>
#include <boost/regex.hpp> #include <boost/regex.hpp>
#include <boost/range/iterator_range.hpp> #include <boost/range/iterator_range_core.hpp>
#include <boost/range/begin.hpp> #include <boost/range/begin.hpp>
#include <boost/range/end.hpp> #include <boost/range/end.hpp>
#include <boost/range/iterator.hpp> #include <boost/range/iterator.hpp>

View File

@ -13,7 +13,7 @@
#include <boost/algorithm/string/config.hpp> #include <boost/algorithm/string/config.hpp>
#include <boost/range/iterator_range.hpp> #include <boost/range/iterator_range_core.hpp>
#include <boost/range/begin.hpp> #include <boost/range/begin.hpp>
#include <boost/range/end.hpp> #include <boost/range/end.hpp>
#include <boost/range/iterator.hpp> #include <boost/range/iterator.hpp>

View File

@ -17,7 +17,7 @@
#include <boost/range/end.hpp> #include <boost/range/end.hpp>
#include <boost/range/const_iterator.hpp> #include <boost/range/const_iterator.hpp>
#include <boost/range/as_literal.hpp> #include <boost/range/as_literal.hpp>
#include <boost/range/iterator_range.hpp> #include <boost/range/iterator_range_core.hpp>
#include <boost/algorithm/string/detail/trim.hpp> #include <boost/algorithm/string/detail/trim.hpp>
#include <boost/algorithm/string/classification.hpp> #include <boost/algorithm/string/classification.hpp>

View File

@ -34,6 +34,7 @@
#elif defined(BOOST_ENABLE_ASSERT_HANDLER) #elif defined(BOOST_ENABLE_ASSERT_HANDLER)
#include <boost/config.hpp>
#include <boost/current_function.hpp> #include <boost/current_function.hpp>
namespace boost namespace boost
@ -42,7 +43,7 @@ namespace boost
char const * function, char const * file, long line); // user defined char const * function, char const * file, long line); // user defined
} // namespace boost } // namespace boost
#define BOOST_ASSERT(expr) ((expr) \ #define BOOST_ASSERT(expr) (BOOST_LIKELY(!!(expr)) \
? ((void)0) \ ? ((void)0) \
: ::boost::assertion_failed(#expr, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__)) : ::boost::assertion_failed(#expr, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__))
@ -63,6 +64,7 @@ namespace boost
#elif defined(BOOST_ENABLE_ASSERT_HANDLER) #elif defined(BOOST_ENABLE_ASSERT_HANDLER)
#include <boost/config.hpp>
#include <boost/current_function.hpp> #include <boost/current_function.hpp>
namespace boost namespace boost
@ -71,7 +73,7 @@ namespace boost
char const * function, char const * file, long line); // user defined char const * function, char const * file, long line); // user defined
} // namespace boost } // namespace boost
#define BOOST_ASSERT_MSG(expr, msg) ((expr) \ #define BOOST_ASSERT_MSG(expr, msg) (BOOST_LIKELY(!!(expr)) \
? ((void)0) \ ? ((void)0) \
: ::boost::assertion_failed_msg(#expr, msg, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__)) : ::boost::assertion_failed_msg(#expr, msg, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__))
@ -80,6 +82,7 @@ namespace boost
#define BOOST_ASSERT_HPP #define BOOST_ASSERT_HPP
#include <cstdlib> #include <cstdlib>
#include <iostream> #include <iostream>
#include <boost/config.hpp>
#include <boost/current_function.hpp> #include <boost/current_function.hpp>
// IDE's like Visual Studio perform better if output goes to std::cout or // IDE's like Visual Studio perform better if output goes to std::cout or
@ -94,7 +97,9 @@ namespace boost
{ {
namespace detail namespace detail
{ {
inline void assertion_failed_msg(char const * expr, char const * msg, char const * function, // Note: The template is needed to make the function non-inline and avoid linking errors
template< typename CharT >
BOOST_NOINLINE void assertion_failed_msg(CharT const * expr, char const * msg, char const * function,
char const * file, long line) char const * file, long line)
{ {
BOOST_ASSERT_MSG_OSTREAM BOOST_ASSERT_MSG_OSTREAM
@ -113,7 +118,7 @@ namespace boost
} // detail } // detail
#endif #endif
#define BOOST_ASSERT_MSG(expr, msg) ((expr) \ #define BOOST_ASSERT_MSG(expr, msg) (BOOST_LIKELY(!!(expr)) \
? ((void)0) \ ? ((void)0) \
: ::boost::assertion::detail::assertion_failed_msg(#expr, msg, \ : ::boost::assertion::detail::assertion_failed_msg(#expr, msg, \
BOOST_CURRENT_FUNCTION, __FILE__, __LINE__)) BOOST_CURRENT_FUNCTION, __FILE__, __LINE__))

View File

@ -11,7 +11,7 @@
#include <boost/atomic/atomic.hpp> #include <boost/atomic/atomic.hpp>
#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE #ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once #pragma once
#endif #endif

View File

@ -22,7 +22,7 @@
#include <boost/mpl/and.hpp> #include <boost/mpl/and.hpp>
#endif #endif
#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE #ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once #pragma once
#endif #endif
@ -60,6 +60,10 @@ namespace boost {
#define BOOST_ATOMIC_LLONG_LOCK_FREE 0 #define BOOST_ATOMIC_LLONG_LOCK_FREE 0
#endif #endif
#ifndef BOOST_ATOMIC_INT128_LOCK_FREE
#define BOOST_ATOMIC_INT128_LOCK_FREE 0
#endif
#ifndef BOOST_ATOMIC_POINTER_LOCK_FREE #ifndef BOOST_ATOMIC_POINTER_LOCK_FREE
#define BOOST_ATOMIC_POINTER_LOCK_FREE 0 #define BOOST_ATOMIC_POINTER_LOCK_FREE 0
#endif #endif
@ -112,11 +116,18 @@ private:
mpl::and_< boost::is_integral<T>, boost::is_signed<T> >::value mpl::and_< boost::is_integral<T>, boost::is_signed<T> >::value
#endif #endif
> super; > super;
public: typedef typename super::value_arg_type value_arg_type;
atomic(void) BOOST_NOEXCEPT : super() {}
BOOST_CONSTEXPR atomic(value_type v) BOOST_NOEXCEPT : super(v) {}
value_type operator=(value_type v) volatile BOOST_NOEXCEPT public:
BOOST_DEFAULTED_FUNCTION(atomic(void), BOOST_NOEXCEPT {})
// NOTE: The constructor is made explicit because gcc 4.7 complains that
// operator=(value_arg_type) is considered ambiguous with operator=(atomic const&)
// in assignment expressions, even though conversion to atomic<> is less preferred
// than conversion to value_arg_type.
explicit BOOST_CONSTEXPR atomic(value_arg_type v) BOOST_NOEXCEPT : super(v) {}
value_type operator=(value_arg_type v) volatile BOOST_NOEXCEPT
{ {
this->store(v); this->store(v);
return v; return v;
@ -127,14 +138,8 @@ public:
return this->load(); return this->load();
} }
#ifdef BOOST_NO_CXX11_DELETED_FUNCTIONS BOOST_DELETED_FUNCTION(atomic(atomic const&))
private: BOOST_DELETED_FUNCTION(atomic& operator=(atomic const&) volatile)
atomic(const atomic &) /* =delete */ ;
atomic & operator=(const atomic &) volatile /* =delete */ ;
#else
atomic(const atomic &) = delete;
atomic & operator=(const atomic &) volatile = delete;
#endif
}; };
typedef atomic<char> atomic_char; typedef atomic<char> atomic_char;
@ -190,25 +195,9 @@ typedef atomic<uintmax_t> atomic_uintmax_t;
typedef atomic<std::size_t> atomic_size_t; typedef atomic<std::size_t> atomic_size_t;
typedef atomic<std::ptrdiff_t> atomic_ptrdiff_t; typedef atomic<std::ptrdiff_t> atomic_ptrdiff_t;
// PGI seems to not support intptr_t/uintptr_t properly. BOOST_HAS_STDINT_H is not defined for this compiler by Boost.Config. #if defined(BOOST_HAS_INTPTR_T)
#if !defined(__PGIC__)
#if (defined(BOOST_WINDOWS) && !defined(_WIN32_WCE)) \
|| (defined(_XOPEN_UNIX) && (_XOPEN_UNIX+0 > 0) && !defined(__UCLIBC__)) \
|| defined(__CYGWIN__) \
|| defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) \
|| defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
typedef atomic<intptr_t> atomic_intptr_t; typedef atomic<intptr_t> atomic_intptr_t;
typedef atomic<uintptr_t> atomic_uintptr_t; typedef atomic<uintptr_t> atomic_uintptr_t;
#elif defined(__GNUC__) || defined(__clang__)
#if defined(__INTPTR_TYPE__)
typedef atomic< __INTPTR_TYPE__ > atomic_intptr_t;
#endif
#if defined(__UINTPTR_TYPE__)
typedef atomic< __UINTPTR_TYPE__ > atomic_uintptr_t;
#endif
#endif
#endif #endif
#ifndef BOOST_ATOMIC_FLAG_LOCK_FREE #ifndef BOOST_ATOMIC_FLAG_LOCK_FREE
@ -229,9 +218,11 @@ public:
{ {
v_.store(false, order); v_.store(false, order);
} }
BOOST_DELETED_FUNCTION(atomic_flag(atomic_flag const&))
BOOST_DELETED_FUNCTION(atomic_flag& operator=(atomic_flag const&))
private: private:
atomic_flag(const atomic_flag &) /* = delete */ ;
atomic_flag & operator=(const atomic_flag &) /* = delete */ ;
atomic<bool> v_; atomic<bool> v_;
}; };
#endif #endif

View File

@ -19,7 +19,7 @@
#include <boost/atomic/detail/config.hpp> #include <boost/atomic/detail/config.hpp>
#include <boost/atomic/detail/lockpool.hpp> #include <boost/atomic/detail/lockpool.hpp>
#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE #ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once #pragma once
#endif #endif
@ -155,7 +155,8 @@ namespace detail {
inline memory_order inline memory_order
calculate_failure_order(memory_order order) calculate_failure_order(memory_order order)
{ {
switch(order) { switch(order)
{
case memory_order_acq_rel: case memory_order_acq_rel:
return memory_order_acquire; return memory_order_acquire;
case memory_order_release: case memory_order_release:
@ -172,11 +173,12 @@ private:
typedef base_atomic this_type; typedef base_atomic this_type;
typedef T value_type; typedef T value_type;
typedef lockpool::scoped_lock guard_type; typedef lockpool::scoped_lock guard_type;
typedef char storage_type[sizeof(value_type)];
protected:
typedef value_type const& value_arg_type;
public: public:
base_atomic(void) {} BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
BOOST_CONSTEXPR explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(v) BOOST_CONSTEXPR explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(v)
{} {}
@ -249,15 +251,16 @@ public:
} }
BOOST_ATOMIC_DECLARE_BASE_OPERATORS BOOST_ATOMIC_DECLARE_BASE_OPERATORS
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private: private:
char * storage_ptr() volatile const BOOST_NOEXCEPT char * storage_ptr() volatile const BOOST_NOEXCEPT
{ {
return const_cast<char *>(&reinterpret_cast<char const volatile &>(v_)); return const_cast<char *>(&reinterpret_cast<char const volatile &>(v_));
} }
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
T v_; T v_;
}; };
@ -269,9 +272,13 @@ private:
typedef T value_type; typedef T value_type;
typedef T difference_type; typedef T difference_type;
typedef lockpool::scoped_lock guard_type; typedef lockpool::scoped_lock guard_type;
protected:
typedef value_type value_arg_type;
public: public:
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
base_atomic(void) {}
void void
store(value_type v, memory_order /*order*/ = memory_order_seq_cst) volatile BOOST_NOEXCEPT store(value_type v, memory_order /*order*/ = memory_order_seq_cst) volatile BOOST_NOEXCEPT
@ -381,9 +388,11 @@ public:
} }
BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private: private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
value_type v_; value_type v_;
}; };
@ -393,11 +402,15 @@ class base_atomic<T *, void *, Size, Sign>
private: private:
typedef base_atomic this_type; typedef base_atomic this_type;
typedef T * value_type; typedef T * value_type;
typedef ptrdiff_t difference_type; typedef std::ptrdiff_t difference_type;
typedef lockpool::scoped_lock guard_type; typedef lockpool::scoped_lock guard_type;
protected:
typedef value_type value_arg_type;
public: public:
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
base_atomic(void) {}
void void
store(value_type v, memory_order /*order*/ = memory_order_seq_cst) volatile BOOST_NOEXCEPT store(value_type v, memory_order /*order*/ = memory_order_seq_cst) volatile BOOST_NOEXCEPT
@ -474,9 +487,11 @@ public:
} }
BOOST_ATOMIC_DECLARE_POINTER_OPERATORS BOOST_ATOMIC_DECLARE_POINTER_OPERATORS
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private: private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
value_type v_; value_type v_;
}; };
@ -485,12 +500,16 @@ class base_atomic<void *, void *, Size, Sign>
{ {
private: private:
typedef base_atomic this_type; typedef base_atomic this_type;
typedef ptrdiff_t difference_type; typedef std::ptrdiff_t difference_type;
typedef void * value_type; typedef void * value_type;
typedef lockpool::scoped_lock guard_type; typedef lockpool::scoped_lock guard_type;
protected:
typedef value_type value_arg_type;
public: public:
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
base_atomic(void) {}
void void
store(value_type v, memory_order /*order*/ = memory_order_seq_cst) volatile BOOST_NOEXCEPT store(value_type v, memory_order /*order*/ = memory_order_seq_cst) volatile BOOST_NOEXCEPT
@ -572,9 +591,10 @@ public:
BOOST_ATOMIC_DECLARE_VOID_POINTER_OPERATORS BOOST_ATOMIC_DECLARE_VOID_POINTER_OPERATORS
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private: private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
value_type v_; value_type v_;
}; };

View File

@ -0,0 +1,286 @@
#ifndef BOOST_ATOMIC_DETAIL_CAS128STRONG_HPP
#define BOOST_ATOMIC_DETAIL_CAS128STRONG_HPP
// 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)
//
// Copyright (c) 2011 Helge Bahmann
// Copyright (c) 2013 Tim Blechmann, Andrey Semashev
// Build 128-bit atomic operation on integers/UDTs from platform_cmpxchg128_strong
// primitive. It is assumed that 128-bit loads/stores are not
// atomic, so they are implemented through platform_load128/platform_store128.
#include <string.h>
#include <cstddef>
#include <boost/cstdint.hpp>
#include <boost/memory_order.hpp>
#include <boost/atomic/detail/config.hpp>
#include <boost/atomic/detail/base.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
namespace boost {
namespace atomics {
namespace detail {
/* integral types */
template<typename T, bool Sign>
class base_atomic<T, int, 16, Sign>
{
private:
typedef base_atomic this_type;
typedef T value_type;
typedef T difference_type;
protected:
typedef value_type value_arg_type;
public:
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
void
store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
{
platform_fence_before_store(order);
platform_store128(v, &v_);
platform_fence_after_store(order);
}
value_type
load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
{
value_type v = platform_load128(&v_);
platform_fence_after_load(order);
return v;
}
value_type
exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
{
value_type original = load(memory_order_relaxed);
do {
} while (!compare_exchange_weak(original, v, order, memory_order_relaxed));
return original;
}
bool
compare_exchange_weak(
value_type & expected,
value_type desired,
memory_order success_order,
memory_order failure_order) volatile BOOST_NOEXCEPT
{
return compare_exchange_strong(expected, desired, success_order, failure_order);
}
bool
compare_exchange_strong(
value_type & expected,
value_type desired,
memory_order success_order,
memory_order failure_order) volatile BOOST_NOEXCEPT
{
platform_fence_before(success_order);
bool success = platform_cmpxchg128_strong(expected, desired, &v_);
if (success) {
platform_fence_after(success_order);
} else {
platform_fence_after(failure_order);
}
return success;
}
value_type
fetch_add(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
{
value_type original = load(memory_order_relaxed);
do {
} while (!compare_exchange_weak(original, original + v, order, memory_order_relaxed));
return original;
}
value_type
fetch_sub(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
{
value_type original = load(memory_order_relaxed);
do {
} while (!compare_exchange_weak(original, original - v, order, memory_order_relaxed));
return original;
}
value_type
fetch_and(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
{
value_type original = load(memory_order_relaxed);
do {
} while (!compare_exchange_weak(original, original & v, order, memory_order_relaxed));
return original;
}
value_type
fetch_or(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
{
value_type original = load(memory_order_relaxed);
do {
} while (!compare_exchange_weak(original, original | v, order, memory_order_relaxed));
return original;
}
value_type
fetch_xor(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
{
value_type original = load(memory_order_relaxed);
do {
} while (!compare_exchange_weak(original, original ^ v, order, memory_order_relaxed));
return original;
}
bool
is_lock_free(void) const volatile BOOST_NOEXCEPT
{
return true;
}
BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private:
value_type v_;
};
/* generic types */
#if defined(BOOST_HAS_INT128)
typedef boost::uint128_type storage128_type;
#else // defined(BOOST_HAS_INT128)
struct BOOST_ALIGNMENT(16) storage128_type
{
uint64_t data[2];
};
inline bool operator== (storage128_type const& left, storage128_type const& right)
{
return left.data[0] == right.data[0] && left.data[1] == right.data[1];
}
inline bool operator!= (storage128_type const& left, storage128_type const& right)
{
return !(left == right);
}
#endif // defined(BOOST_HAS_INT128)
template<typename T, bool Sign>
class base_atomic<T, void, 16, Sign>
{
private:
typedef base_atomic this_type;
typedef T value_type;
typedef storage128_type storage_type;
protected:
typedef value_type const& value_arg_type;
public:
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0)
{
memcpy(&v_, &v, sizeof(value_type));
}
void
store(value_type const& value, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
{
storage_type value_s = 0;
memcpy(&value_s, &value, sizeof(value_type));
platform_fence_before_store(order);
platform_store128(value_s, &v_);
platform_fence_after_store(order);
}
value_type
load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
{
storage_type value_s = platform_load128(&v_);
platform_fence_after_load(order);
value_type value;
memcpy(&value, &value_s, sizeof(value_type));
return value;
}
value_type
exchange(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
{
value_type original = load(memory_order_relaxed);
do {
} while (!compare_exchange_weak(original, v, order, memory_order_relaxed));
return original;
}
bool
compare_exchange_weak(
value_type & expected,
value_type const& desired,
memory_order success_order,
memory_order failure_order) volatile BOOST_NOEXCEPT
{
return compare_exchange_strong(expected, desired, success_order, failure_order);
}
bool
compare_exchange_strong(
value_type & expected,
value_type const& desired,
memory_order success_order,
memory_order failure_order) volatile BOOST_NOEXCEPT
{
storage_type expected_s = 0, desired_s = 0;
memcpy(&expected_s, &expected, sizeof(value_type));
memcpy(&desired_s, &desired, sizeof(value_type));
platform_fence_before(success_order);
bool success = platform_cmpxchg128_strong(expected_s, desired_s, &v_);
if (success) {
platform_fence_after(success_order);
} else {
platform_fence_after(failure_order);
memcpy(&expected, &expected_s, sizeof(value_type));
}
return success;
}
bool
is_lock_free(void) const volatile BOOST_NOEXCEPT
{
return true;
}
BOOST_ATOMIC_DECLARE_BASE_OPERATORS
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private:
storage_type v_;
};
}
}
}
#endif

View File

@ -12,13 +12,14 @@
// Build 8-, 16- and 32-bit atomic operations from // Build 8-, 16- and 32-bit atomic operations from
// a platform_cmpxchg32_strong primitive. // a platform_cmpxchg32_strong primitive.
#include <string.h>
#include <cstddef> #include <cstddef>
#include <boost/cstdint.hpp> #include <boost/cstdint.hpp>
#include <boost/memory_order.hpp> #include <boost/memory_order.hpp>
#include <boost/atomic/detail/config.hpp> #include <boost/atomic/detail/config.hpp>
#include <boost/atomic/detail/base.hpp> #include <boost/atomic/detail/base.hpp>
#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE #ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once #pragma once
#endif #endif
@ -31,13 +32,18 @@ namespace detail {
template<typename T, bool Sign> template<typename T, bool Sign>
class base_atomic<T, int, 1, Sign> class base_atomic<T, int, 1, Sign>
{ {
private:
typedef base_atomic this_type; typedef base_atomic this_type;
typedef T value_type; typedef T value_type;
typedef T difference_type; typedef T difference_type;
typedef uint32_t storage_type; typedef uint32_t storage_type;
protected:
typedef value_type value_arg_type;
public: public:
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
base_atomic(void) {}
void void
store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
@ -150,22 +156,29 @@ public:
} }
BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private: private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
storage_type v_; storage_type v_;
}; };
template<typename T, bool Sign> template<typename T, bool Sign>
class base_atomic<T, int, 2, Sign> class base_atomic<T, int, 2, Sign>
{ {
private:
typedef base_atomic this_type; typedef base_atomic this_type;
typedef T value_type; typedef T value_type;
typedef T difference_type; typedef T difference_type;
typedef uint32_t storage_type; typedef uint32_t storage_type;
protected:
typedef value_type value_arg_type;
public: public:
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
base_atomic(void) {}
void void
store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
@ -278,21 +291,28 @@ public:
} }
BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private: private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
storage_type v_; storage_type v_;
}; };
template<typename T, bool Sign> template<typename T, bool Sign>
class base_atomic<T, int, 4, Sign> class base_atomic<T, int, 4, Sign>
{ {
private:
typedef base_atomic this_type; typedef base_atomic this_type;
typedef T value_type; typedef T value_type;
typedef T difference_type; typedef T difference_type;
protected:
typedef value_type value_arg_type;
public: public:
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
base_atomic(void) {}
void void
store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
@ -401,9 +421,11 @@ public:
} }
BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private: private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
value_type v_; value_type v_;
}; };
@ -412,12 +434,17 @@ private:
template<bool Sign> template<bool Sign>
class base_atomic<void *, void *, 4, Sign> class base_atomic<void *, void *, 4, Sign>
{ {
private:
typedef base_atomic this_type; typedef base_atomic this_type;
typedef void * value_type; typedef void * value_type;
typedef ptrdiff_t difference_type; typedef std::ptrdiff_t difference_type;
protected:
typedef value_type value_arg_type;
public: public:
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
base_atomic(void) {}
void void
store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
@ -499,21 +526,28 @@ public:
} }
BOOST_ATOMIC_DECLARE_VOID_POINTER_OPERATORS BOOST_ATOMIC_DECLARE_VOID_POINTER_OPERATORS
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private: private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
value_type v_; value_type v_;
}; };
template<typename T, bool Sign> template<typename T, bool Sign>
class base_atomic<T *, void *, 4, Sign> class base_atomic<T *, void *, 4, Sign>
{ {
private:
typedef base_atomic this_type; typedef base_atomic this_type;
typedef T * value_type; typedef T * value_type;
typedef ptrdiff_t difference_type; typedef std::ptrdiff_t difference_type;
protected:
typedef value_type value_arg_type;
public: public:
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
base_atomic(void) {}
void void
store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
@ -595,9 +629,11 @@ public:
} }
BOOST_ATOMIC_DECLARE_POINTER_OPERATORS BOOST_ATOMIC_DECLARE_POINTER_OPERATORS
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private: private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
value_type v_; value_type v_;
}; };
@ -606,17 +642,21 @@ private:
template<typename T, bool Sign> template<typename T, bool Sign>
class base_atomic<T, void, 1, Sign> class base_atomic<T, void, 1, Sign>
{ {
private:
typedef base_atomic this_type; typedef base_atomic this_type;
typedef T value_type; typedef T value_type;
typedef uint32_t storage_type; typedef uint32_t storage_type;
protected:
typedef value_type const& value_arg_type;
public: public:
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0)
{ {
memcpy(&v_, &v, sizeof(value_type)); memcpy(&v_, &v, sizeof(value_type));
} }
base_atomic(void) {}
void void
store(value_type const& v, memory_order order = memory_order_seq_cst) ) volatile BOOST_NOEXCEPT store(value_type const& v, memory_order order = memory_order_seq_cst) ) volatile BOOST_NOEXCEPT
{ {
@ -688,26 +728,32 @@ public:
} }
BOOST_ATOMIC_DECLARE_BASE_OPERATORS BOOST_ATOMIC_DECLARE_BASE_OPERATORS
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private: private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
storage_type v_; storage_type v_;
}; };
template<typename T, bool Sign> template<typename T, bool Sign>
class base_atomic<T, void, 2, Sign> class base_atomic<T, void, 2, Sign>
{ {
private:
typedef base_atomic this_type; typedef base_atomic this_type;
typedef T value_type; typedef T value_type;
typedef uint32_t storage_type; typedef uint32_t storage_type;
protected:
typedef value_type const& value_arg_type;
public: public:
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0)
{ {
memcpy(&v_, &v, sizeof(value_type)); memcpy(&v_, &v, sizeof(value_type));
} }
base_atomic(void) {}
void void
store(value_type const& v, memory_order order = memory_order_seq_cst) ) volatile BOOST_NOEXCEPT store(value_type const& v, memory_order order = memory_order_seq_cst) ) volatile BOOST_NOEXCEPT
{ {
@ -780,26 +826,32 @@ public:
} }
BOOST_ATOMIC_DECLARE_BASE_OPERATORS BOOST_ATOMIC_DECLARE_BASE_OPERATORS
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private: private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
storage_type v_; storage_type v_;
}; };
template<typename T, bool Sign> template<typename T, bool Sign>
class base_atomic<T, void, 4, Sign> class base_atomic<T, void, 4, Sign>
{ {
private:
typedef base_atomic this_type; typedef base_atomic this_type;
typedef T value_type; typedef T value_type;
typedef uint32_t storage_type; typedef uint32_t storage_type;
protected:
typedef value_type const& value_arg_type;
public: public:
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0)
{ {
memcpy(&v_, &v, sizeof(value_type)); memcpy(&v_, &v, sizeof(value_type));
} }
base_atomic(void) {}
void void
store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
{ {
@ -872,9 +924,11 @@ public:
} }
BOOST_ATOMIC_DECLARE_BASE_OPERATORS BOOST_ATOMIC_DECLARE_BASE_OPERATORS
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private: private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
storage_type v_; storage_type v_;
}; };

View File

@ -9,13 +9,14 @@
// Copyright (c) 2013 Tim Blechmann // Copyright (c) 2013 Tim Blechmann
#include <string.h>
#include <cstddef> #include <cstddef>
#include <boost/cstdint.hpp> #include <boost/cstdint.hpp>
#include <boost/memory_order.hpp> #include <boost/memory_order.hpp>
#include <boost/atomic/detail/config.hpp> #include <boost/atomic/detail/config.hpp>
#include <boost/atomic/detail/base.hpp> #include <boost/atomic/detail/base.hpp>
#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE #ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once #pragma once
#endif #endif
@ -28,13 +29,18 @@ namespace detail {
template<typename T, bool Sign> template<typename T, bool Sign>
class base_atomic<T, int, 1, Sign> class base_atomic<T, int, 1, Sign>
{ {
private:
typedef base_atomic this_type; typedef base_atomic this_type;
typedef T value_type; typedef T value_type;
typedef T difference_type; typedef T difference_type;
typedef uint32_t storage_type; typedef uint32_t storage_type;
protected:
typedef value_type value_arg_type;
public: public:
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
base_atomic(void) {}
void void
store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
@ -92,11 +98,13 @@ public:
memory_order success_order, memory_order success_order,
memory_order failure_order) volatile BOOST_NOEXCEPT memory_order failure_order) volatile BOOST_NOEXCEPT
{ {
for(;;) { while (true)
{
value_type tmp = expected; value_type tmp = expected;
if (compare_exchange_weak(tmp, desired, success_order, failure_order)) if (compare_exchange_weak(tmp, desired, success_order, failure_order))
return true; return true;
if (tmp != expected) { if (tmp != expected)
{
expected = tmp; expected = tmp;
return false; return false;
} }
@ -155,22 +163,29 @@ public:
} }
BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private: private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
storage_type v_; storage_type v_;
}; };
template<typename T, bool Sign> template<typename T, bool Sign>
class base_atomic<T, int, 2, Sign> class base_atomic<T, int, 2, Sign>
{ {
private:
typedef base_atomic this_type; typedef base_atomic this_type;
typedef T value_type; typedef T value_type;
typedef T difference_type; typedef T difference_type;
typedef uint32_t storage_type; typedef uint32_t storage_type;
protected:
typedef value_type value_arg_type;
public: public:
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
base_atomic(void) {}
void void
store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
@ -228,11 +243,13 @@ public:
memory_order success_order, memory_order success_order,
memory_order failure_order) volatile BOOST_NOEXCEPT memory_order failure_order) volatile BOOST_NOEXCEPT
{ {
for(;;) { while (true)
{
value_type tmp = expected; value_type tmp = expected;
if (compare_exchange_weak(tmp, desired, success_order, failure_order)) if (compare_exchange_weak(tmp, desired, success_order, failure_order))
return true; return true;
if (tmp != expected) { if (tmp != expected)
{
expected = tmp; expected = tmp;
return false; return false;
} }
@ -291,21 +308,28 @@ public:
} }
BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private: private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
storage_type v_; storage_type v_;
}; };
template<typename T, bool Sign> template<typename T, bool Sign>
class base_atomic<T, int, 4, Sign> class base_atomic<T, int, 4, Sign>
{ {
private:
typedef base_atomic this_type; typedef base_atomic this_type;
typedef T value_type; typedef T value_type;
typedef T difference_type; typedef T difference_type;
protected:
typedef value_type value_arg_type;
public: public:
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
base_atomic(void) {}
void void
store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
@ -359,11 +383,13 @@ public:
memory_order success_order, memory_order success_order,
memory_order failure_order) volatile BOOST_NOEXCEPT memory_order failure_order) volatile BOOST_NOEXCEPT
{ {
for(;;) { while (true)
{
value_type tmp = expected; value_type tmp = expected;
if (compare_exchange_weak(tmp, desired, success_order, failure_order)) if (compare_exchange_weak(tmp, desired, success_order, failure_order))
return true; return true;
if (tmp != expected) { if (tmp != expected)
{
expected = tmp; expected = tmp;
return false; return false;
} }
@ -422,9 +448,11 @@ public:
} }
BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private: private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
value_type v_; value_type v_;
}; };
@ -433,12 +461,17 @@ private:
template<bool Sign> template<bool Sign>
class base_atomic<void *, void *, 4, Sign> class base_atomic<void *, void *, 4, Sign>
{ {
private:
typedef base_atomic this_type; typedef base_atomic this_type;
typedef void * value_type; typedef void * value_type;
typedef ptrdiff_t difference_type; typedef std::ptrdiff_t difference_type;
protected:
typedef value_type value_arg_type;
public: public:
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
base_atomic(void) {}
void void
store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
@ -492,11 +525,13 @@ public:
memory_order success_order, memory_order success_order,
memory_order failure_order) volatile BOOST_NOEXCEPT memory_order failure_order) volatile BOOST_NOEXCEPT
{ {
for(;;) { while (true)
{
value_type tmp = expected; value_type tmp = expected;
if (compare_exchange_weak(tmp, desired, success_order, failure_order)) if (compare_exchange_weak(tmp, desired, success_order, failure_order))
return true; return true;
if (tmp != expected) { if (tmp != expected)
{
expected = tmp; expected = tmp;
return false; return false;
} }
@ -528,21 +563,28 @@ public:
} }
BOOST_ATOMIC_DECLARE_VOID_POINTER_OPERATORS BOOST_ATOMIC_DECLARE_VOID_POINTER_OPERATORS
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private: private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
value_type v_; value_type v_;
}; };
template<typename T, bool Sign> template<typename T, bool Sign>
class base_atomic<T *, void *, 4, Sign> class base_atomic<T *, void *, 4, Sign>
{ {
private:
typedef base_atomic this_type; typedef base_atomic this_type;
typedef T * value_type; typedef T * value_type;
typedef ptrdiff_t difference_type; typedef std::ptrdiff_t difference_type;
protected:
typedef value_type value_arg_type;
public: public:
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
base_atomic(void) {}
void void
store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
@ -596,11 +638,13 @@ public:
memory_order success_order, memory_order success_order,
memory_order failure_order) volatile BOOST_NOEXCEPT memory_order failure_order) volatile BOOST_NOEXCEPT
{ {
for(;;) { while (true)
{
value_type tmp = expected; value_type tmp = expected;
if (compare_exchange_weak(tmp, desired, success_order, failure_order)) if (compare_exchange_weak(tmp, desired, success_order, failure_order))
return true; return true;
if (tmp != expected) { if (tmp != expected)
{
expected = tmp; expected = tmp;
return false; return false;
} }
@ -632,9 +676,11 @@ public:
} }
BOOST_ATOMIC_DECLARE_POINTER_OPERATORS BOOST_ATOMIC_DECLARE_POINTER_OPERATORS
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private: private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
value_type v_; value_type v_;
}; };
@ -643,17 +689,21 @@ private:
template<typename T, bool Sign> template<typename T, bool Sign>
class base_atomic<T, void, 1, Sign> class base_atomic<T, void, 1, Sign>
{ {
private:
typedef base_atomic this_type; typedef base_atomic this_type;
typedef T value_type; typedef T value_type;
typedef uint32_t storage_type; typedef uint32_t storage_type;
protected:
typedef value_type const& value_arg_type;
public: public:
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0)
{ {
memcpy(&v_, &v, sizeof(value_type)); memcpy(&v_, &v, sizeof(value_type));
} }
base_atomic(void) {}
void void
store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
{ {
@ -716,11 +766,13 @@ public:
memory_order success_order, memory_order success_order,
memory_order failure_order) volatile BOOST_NOEXCEPT memory_order failure_order) volatile BOOST_NOEXCEPT
{ {
for(;;) { while (true)
{
value_type tmp = expected; value_type tmp = expected;
if (compare_exchange_weak(tmp, desired, success_order, failure_order)) if (compare_exchange_weak(tmp, desired, success_order, failure_order))
return true; return true;
if (tmp != expected) { if (tmp != expected)
{
expected = tmp; expected = tmp;
return false; return false;
} }
@ -734,26 +786,32 @@ public:
} }
BOOST_ATOMIC_DECLARE_BASE_OPERATORS BOOST_ATOMIC_DECLARE_BASE_OPERATORS
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private: private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
storage_type v_; storage_type v_;
}; };
template<typename T, bool Sign> template<typename T, bool Sign>
class base_atomic<T, void, 2, Sign> class base_atomic<T, void, 2, Sign>
{ {
private:
typedef base_atomic this_type; typedef base_atomic this_type;
typedef T value_type; typedef T value_type;
typedef uint32_t storage_type; typedef uint32_t storage_type;
protected:
typedef value_type const& value_arg_type;
public: public:
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0)
{ {
memcpy(&v_, &v, sizeof(value_type)); memcpy(&v_, &v, sizeof(value_type));
} }
base_atomic(void) {}
void void
store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
{ {
@ -816,11 +874,13 @@ public:
memory_order success_order, memory_order success_order,
memory_order failure_order) volatile BOOST_NOEXCEPT memory_order failure_order) volatile BOOST_NOEXCEPT
{ {
for(;;) { while (true)
{
value_type tmp = expected; value_type tmp = expected;
if (compare_exchange_weak(tmp, desired, success_order, failure_order)) if (compare_exchange_weak(tmp, desired, success_order, failure_order))
return true; return true;
if (tmp != expected) { if (tmp != expected)
{
expected = tmp; expected = tmp;
return false; return false;
} }
@ -834,26 +894,32 @@ public:
} }
BOOST_ATOMIC_DECLARE_BASE_OPERATORS BOOST_ATOMIC_DECLARE_BASE_OPERATORS
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private: private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
storage_type v_; storage_type v_;
}; };
template<typename T, bool Sign> template<typename T, bool Sign>
class base_atomic<T, void, 4, Sign> class base_atomic<T, void, 4, Sign>
{ {
private:
typedef base_atomic this_type; typedef base_atomic this_type;
typedef T value_type; typedef T value_type;
typedef uint32_t storage_type; typedef uint32_t storage_type;
protected:
typedef value_type const& value_arg_type;
public: public:
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0)
{ {
memcpy(&v_, &v, sizeof(value_type)); memcpy(&v_, &v, sizeof(value_type));
} }
base_atomic(void) {}
void void
store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
{ {
@ -916,11 +982,13 @@ public:
memory_order success_order, memory_order success_order,
memory_order failure_order) volatile BOOST_NOEXCEPT memory_order failure_order) volatile BOOST_NOEXCEPT
{ {
for(;;) { while (true)
{
value_type tmp = expected; value_type tmp = expected;
if (compare_exchange_weak(tmp, desired, success_order, failure_order)) if (compare_exchange_weak(tmp, desired, success_order, failure_order))
return true; return true;
if (tmp != expected) { if (tmp != expected)
{
expected = tmp; expected = tmp;
return false; return false;
} }
@ -934,9 +1002,11 @@ public:
} }
BOOST_ATOMIC_DECLARE_BASE_OPERATORS BOOST_ATOMIC_DECLARE_BASE_OPERATORS
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private: private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
storage_type v_; storage_type v_;
}; };

View File

@ -0,0 +1,247 @@
#ifndef BOOST_ATOMIC_DETAIL_CAS64STRONG_PTR_HPP
#define BOOST_ATOMIC_DETAIL_CAS64STRONG_PTR_HPP
// 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)
//
// Copyright (c) 2011 Helge Bahmann
// Copyright (c) 2013 Tim Blechmann
// Build 64-bit atomic operation on pointers from platform_cmpxchg64_strong
// primitive. It is assumed that 64-bit loads/stores are not
// atomic, so they are implemented through platform_load64/platform_store64.
//
// The reason for extracting pointer specializations to a separate header is
// that 64-bit CAS is available on some 32-bit platforms (notably, x86).
// On these platforms there is no need for 64-bit pointer specializations,
// since they will never be used.
#include <string.h>
#include <cstddef>
#include <boost/cstdint.hpp>
#include <boost/memory_order.hpp>
#include <boost/atomic/detail/config.hpp>
#include <boost/atomic/detail/base.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
namespace boost {
namespace atomics {
namespace detail {
/* pointer types */
template<bool Sign>
class base_atomic<void *, void *, 8, Sign>
{
private:
typedef base_atomic this_type;
typedef void * value_type;
typedef std::ptrdiff_t difference_type;
protected:
typedef value_type value_arg_type;
public:
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
void
store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
{
platform_fence_before_store(order);
platform_store64(v, &v_);
platform_fence_after_store(order);
}
value_type
load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
{
value_type v = platform_load64(&v_);
platform_fence_after_load(order);
return v;
}
value_type
exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
{
value_type original = load(memory_order_relaxed);
do {
} while (!compare_exchange_weak(original, v, order, memory_order_relaxed));
return original;
}
bool
compare_exchange_weak(
value_type & expected,
value_type desired,
memory_order success_order,
memory_order failure_order) volatile BOOST_NOEXCEPT
{
return compare_exchange_strong(expected, desired, success_order, failure_order);
}
bool
compare_exchange_strong(
value_type & expected,
value_type desired,
memory_order success_order,
memory_order failure_order) volatile BOOST_NOEXCEPT
{
platform_fence_before(success_order);
bool success = platform_cmpxchg64_strong(expected, desired, &v_);
if (success) {
platform_fence_after(success_order);
} else {
platform_fence_after(failure_order);
}
return success;
}
value_type
fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
{
value_type original = load(memory_order_relaxed);
do {
} while (!compare_exchange_weak(original, (char*)original + v, order, memory_order_relaxed));
return original;
}
value_type
fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
{
value_type original = load(memory_order_relaxed);
do {
} while (!compare_exchange_weak(original, (char*)original - v, order, memory_order_relaxed));
return original;
}
bool
is_lock_free(void) const volatile BOOST_NOEXCEPT
{
return true;
}
BOOST_ATOMIC_DECLARE_VOID_POINTER_OPERATORS
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private:
value_type v_;
};
template<typename T, bool Sign>
class base_atomic<T *, void *, 8, Sign>
{
private:
typedef base_atomic this_type;
typedef T * value_type;
typedef std::ptrdiff_t difference_type;
protected:
typedef value_type value_arg_type;
public:
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
void
store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
{
platform_fence_before_store(order);
platform_store64(v, &v_);
platform_fence_after_store(order);
}
value_type
load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
{
value_type v = platform_load64(&v_);
platform_fence_after_load(order);
return v;
}
value_type
exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
{
value_type original = load(memory_order_relaxed);
do {
} while (!compare_exchange_weak(original, v, order, memory_order_relaxed));
return original;
}
bool
compare_exchange_weak(
value_type & expected,
value_type desired,
memory_order success_order,
memory_order failure_order) volatile BOOST_NOEXCEPT
{
return compare_exchange_strong(expected, desired, success_order, failure_order);
}
bool
compare_exchange_strong(
value_type & expected,
value_type desired,
memory_order success_order,
memory_order failure_order) volatile BOOST_NOEXCEPT
{
platform_fence_before(success_order);
bool success = platform_cmpxchg64_strong(expected, desired, &v_);
if (success) {
platform_fence_after(success_order);
} else {
platform_fence_after(failure_order);
}
return success;
}
value_type
fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
{
value_type original = load(memory_order_relaxed);
do {
} while (!compare_exchange_weak(original, original + v, order, memory_order_relaxed));
return original;
}
value_type
fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
{
value_type original = load(memory_order_relaxed);
do {
} while (!compare_exchange_weak(original, original - v, order, memory_order_relaxed));
return original;
}
bool
is_lock_free(void) const volatile BOOST_NOEXCEPT
{
return true;
}
BOOST_ATOMIC_DECLARE_POINTER_OPERATORS
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private:
value_type v_;
};
}
}
}
#endif

View File

@ -8,17 +8,18 @@
// Copyright (c) 2011 Helge Bahmann // Copyright (c) 2011 Helge Bahmann
// Copyright (c) 2013 Tim Blechmann // Copyright (c) 2013 Tim Blechmann
// Build 64-bit atomic operation from platform_cmpxchg64_strong // Build 64-bit atomic operation on integers/UDTs from platform_cmpxchg64_strong
// primitive. It is assumed that 64-bit loads/stores are not // primitive. It is assumed that 64-bit loads/stores are not
// atomic, so they are funnelled through cmpxchg as well. // atomic, so they are implemented through platform_load64/platform_store64.
#include <string.h>
#include <cstddef> #include <cstddef>
#include <boost/cstdint.hpp> #include <boost/cstdint.hpp>
#include <boost/memory_order.hpp> #include <boost/memory_order.hpp>
#include <boost/atomic/detail/config.hpp> #include <boost/atomic/detail/config.hpp>
#include <boost/atomic/detail/base.hpp> #include <boost/atomic/detail/base.hpp>
#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE #ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once #pragma once
#endif #endif
@ -31,12 +32,17 @@ namespace detail {
template<typename T, bool Sign> template<typename T, bool Sign>
class base_atomic<T, int, 8, Sign> class base_atomic<T, int, 8, Sign>
{ {
private:
typedef base_atomic this_type; typedef base_atomic this_type;
typedef T value_type; typedef T value_type;
typedef T difference_type; typedef T difference_type;
protected:
typedef value_type value_arg_type;
public: public:
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
base_atomic(void) {}
void void
store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
@ -145,203 +151,11 @@ public:
} }
BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private: private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
value_type v_;
};
/* pointer types */
template<bool Sign>
class base_atomic<void *, void *, 8, Sign>
{
typedef base_atomic this_type;
typedef void * value_type;
typedef ptrdiff_t difference_type;
public:
BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
base_atomic(void) {}
void
store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
{
platform_fence_before_store(order);
platform_store64(v, &v_);
platform_fence_after_store(order);
}
value_type
load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
{
value_type v = platform_load64(&v_);
platform_fence_after_load(order);
return v;
}
value_type
exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
{
value_type original = load(memory_order_relaxed);
do {
} while (!compare_exchange_weak(original, v, order, memory_order_relaxed));
return original;
}
bool
compare_exchange_weak(
value_type & expected,
value_type desired,
memory_order success_order,
memory_order failure_order) volatile BOOST_NOEXCEPT
{
return compare_exchange_strong(expected, desired, success_order, failure_order);
}
bool
compare_exchange_strong(
value_type & expected,
value_type desired,
memory_order success_order,
memory_order failure_order) volatile BOOST_NOEXCEPT
{
platform_fence_before(success_order);
bool success = platform_cmpxchg64_strong(expected, desired, &v_);
if (success) {
platform_fence_after(success_order);
} else {
platform_fence_after(failure_order);
}
return success;
}
value_type
fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
{
value_type original = load(memory_order_relaxed);
do {
} while (!compare_exchange_weak(original, (char*)original + v, order, memory_order_relaxed));
return original;
}
value_type
fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
{
value_type original = load(memory_order_relaxed);
do {
} while (!compare_exchange_weak(original, (char*)original - v, order, memory_order_relaxed));
return original;
}
bool
is_lock_free(void) const volatile BOOST_NOEXCEPT
{
return true;
}
BOOST_ATOMIC_DECLARE_VOID_POINTER_OPERATORS
private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
value_type v_;
};
template<typename T, bool Sign>
class base_atomic<T *, void *, 8, Sign>
{
typedef base_atomic this_type;
typedef T * value_type;
typedef ptrdiff_t difference_type;
public:
BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
base_atomic(void) {}
void
store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
{
platform_fence_before_store(order);
platform_store64(v, &v_);
platform_fence_after_store(order);
}
value_type
load(memory_order order = memory_order_seq_cst) const volatile BOOST_NOEXCEPT
{
value_type v = platform_load64(&v_);
platform_fence_after_load(order);
return v;
}
value_type
exchange(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
{
value_type original = load(memory_order_relaxed);
do {
} while (!compare_exchange_weak(original, v, order, memory_order_relaxed));
return original;
}
bool
compare_exchange_weak(
value_type & expected,
value_type desired,
memory_order success_order,
memory_order failure_order) volatile BOOST_NOEXCEPT
{
return compare_exchange_strong(expected, desired, success_order, failure_order);
}
bool
compare_exchange_strong(
value_type & expected,
value_type desired,
memory_order success_order,
memory_order failure_order) volatile BOOST_NOEXCEPT
{
platform_fence_before(success_order);
bool success = platform_cmpxchg64_strong(expected, desired, &v_);
if (success) {
platform_fence_after(success_order);
} else {
platform_fence_after(failure_order);
}
return success;
}
value_type
fetch_add(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
{
value_type original = load(memory_order_relaxed);
do {
} while (!compare_exchange_weak(original, original + v, order, memory_order_relaxed));
return original;
}
value_type
fetch_sub(difference_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
{
value_type original = load(memory_order_relaxed);
do {
} while (!compare_exchange_weak(original, original - v, order, memory_order_relaxed));
return original;
}
bool
is_lock_free(void) const volatile BOOST_NOEXCEPT
{
return true;
}
BOOST_ATOMIC_DECLARE_POINTER_OPERATORS
private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
value_type v_; value_type v_;
}; };
@ -350,15 +164,20 @@ private:
template<typename T, bool Sign> template<typename T, bool Sign>
class base_atomic<T, void, 8, Sign> class base_atomic<T, void, 8, Sign>
{ {
private:
typedef base_atomic this_type; typedef base_atomic this_type;
typedef T value_type; typedef T value_type;
typedef uint64_t storage_type; typedef uint64_t storage_type;
protected:
typedef value_type const& value_arg_type;
public: public:
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0)
{ {
memcpy(&v_, &v, sizeof(value_type)); memcpy(&v_, &v, sizeof(value_type));
} }
base_atomic(void) {}
void void
store(value_type const& value, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT store(value_type const& value, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
@ -430,9 +249,11 @@ public:
} }
BOOST_ATOMIC_DECLARE_BASE_OPERATORS BOOST_ATOMIC_DECLARE_BASE_OPERATORS
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private: private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
storage_type v_; storage_type v_;
}; };

View File

@ -9,46 +9,8 @@
#include <boost/config.hpp> #include <boost/config.hpp>
#if (defined(_MSC_VER) && (_MSC_VER >= 1020)) || defined(__GNUC__) || defined(BOOST_CLANG) || defined(BOOST_INTEL) || defined(__COMO__) || defined(__DMC__) #ifdef BOOST_HAS_PRAGMA_ONCE
#define BOOST_ATOMIC_HAS_PRAGMA_ONCE
#endif
#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE
#pragma once #pragma once
#endif #endif
///////////////////////////////////////////////////////////////////////////////
// Set up dll import/export options
#if (defined(BOOST_ATOMIC_DYN_LINK) || defined(BOOST_ALL_DYN_LINK)) && \
!defined(BOOST_ATOMIC_STATIC_LINK)
#if defined(BOOST_ATOMIC_SOURCE)
#define BOOST_ATOMIC_DECL BOOST_SYMBOL_EXPORT
#define BOOST_ATOMIC_BUILD_DLL
#else
#define BOOST_ATOMIC_DECL BOOST_SYMBOL_IMPORT
#endif
#endif // building a shared library
#ifndef BOOST_ATOMIC_DECL
#define BOOST_ATOMIC_DECL
#endif
///////////////////////////////////////////////////////////////////////////////
// Auto library naming
#if !defined(BOOST_ATOMIC_SOURCE) && !defined(BOOST_ALL_NO_LIB) && \
!defined(BOOST_ATOMIC_NO_LIB)
#define BOOST_LIB_NAME boost_atomic
// tell the auto-link code to select a dll when required:
#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_ATOMIC_DYN_LINK)
#define BOOST_DYN_LINK
#endif
#include <boost/config/auto_link.hpp>
#endif // auto-linking disabled
#endif #endif

View File

@ -12,7 +12,7 @@
#include <boost/atomic/detail/base.hpp> #include <boost/atomic/detail/base.hpp>
#include <boost/atomic/detail/builder.hpp> #include <boost/atomic/detail/builder.hpp>
#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE #ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once #pragma once
#endif #endif

View File

@ -10,11 +10,10 @@
// Copyright (c) 2013 Tim Blechmann // Copyright (c) 2013 Tim Blechmann
// ARM Code by Phil Endecott, based on other architectures. // ARM Code by Phil Endecott, based on other architectures.
#include <cstddef>
#include <boost/cstdint.hpp> #include <boost/cstdint.hpp>
#include <boost/atomic/detail/config.hpp> #include <boost/atomic/detail/config.hpp>
#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE #ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once #pragma once
#endif #endif
@ -67,29 +66,27 @@ namespace detail {
// to annotate the conditional instructions. These are ignored in other modes (e.g. v6), // to annotate the conditional instructions. These are ignored in other modes (e.g. v6),
// so they can always be present. // so they can always be present.
#if defined(__thumb__) && !defined(__ARM_ARCH_7A__) #if defined(__thumb__) && !defined(__thumb2__)
// FIXME also other v7 variants.
#define BOOST_ATOMIC_ARM_ASM_START(TMPREG) "adr " #TMPREG ", 1f\n" "bx " #TMPREG "\n" ".arm\n" ".align 4\n" "1: " #define BOOST_ATOMIC_ARM_ASM_START(TMPREG) "adr " #TMPREG ", 1f\n" "bx " #TMPREG "\n" ".arm\n" ".align 4\n" "1: "
#define BOOST_ATOMIC_ARM_ASM_END(TMPREG) "adr " #TMPREG ", 1f + 1\n" "bx " #TMPREG "\n" ".thumb\n" ".align 2\n" "1: " #define BOOST_ATOMIC_ARM_ASM_END(TMPREG) "adr " #TMPREG ", 1f + 1\n" "bx " #TMPREG "\n" ".thumb\n" ".align 2\n" "1: "
#else #else
// The tmpreg is wasted in this case, which is non-optimal. // The tmpreg is wasted in this case, which is non-optimal.
#define BOOST_ATOMIC_ARM_ASM_START(TMPREG) #define BOOST_ATOMIC_ARM_ASM_START(TMPREG)
#define BOOST_ATOMIC_ARM_ASM_END(TMPREG) #define BOOST_ATOMIC_ARM_ASM_END(TMPREG)
#endif #endif
#if defined(__ARM_ARCH_7A__) #if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_7S__)
// FIXME ditto.
#define BOOST_ATOMIC_ARM_DMB "dmb\n" #define BOOST_ATOMIC_ARM_DMB "dmb\n"
#else #else
#define BOOST_ATOMIC_ARM_DMB "mcr\tp15, 0, r0, c7, c10, 5\n" #define BOOST_ATOMIC_ARM_DMB "mcr\tp15, 0, r0, c7, c10, 5\n"
#endif #endif
inline void inline void
arm_barrier(void) arm_barrier(void) BOOST_NOEXCEPT
{ {
int brtmp; int brtmp;
__asm__ __volatile__ ( __asm__ __volatile__
(
BOOST_ATOMIC_ARM_ASM_START(%0) BOOST_ATOMIC_ARM_ASM_START(%0)
BOOST_ATOMIC_ARM_DMB BOOST_ATOMIC_ARM_DMB
BOOST_ATOMIC_ARM_ASM_END(%0) BOOST_ATOMIC_ARM_ASM_END(%0)
@ -98,9 +95,10 @@ arm_barrier(void)
} }
inline void inline void
platform_fence_before(memory_order order) platform_fence_before(memory_order order) BOOST_NOEXCEPT
{
switch(order)
{ {
switch(order) {
case memory_order_release: case memory_order_release:
case memory_order_acq_rel: case memory_order_acq_rel:
case memory_order_seq_cst: case memory_order_seq_cst:
@ -111,9 +109,10 @@ platform_fence_before(memory_order order)
} }
inline void inline void
platform_fence_after(memory_order order) platform_fence_after(memory_order order) BOOST_NOEXCEPT
{
switch(order)
{ {
switch(order) {
case memory_order_acquire: case memory_order_acquire:
case memory_order_acq_rel: case memory_order_acq_rel:
case memory_order_seq_cst: case memory_order_seq_cst:
@ -123,31 +122,32 @@ platform_fence_after(memory_order order)
} }
inline void inline void
platform_fence_before_store(memory_order order) platform_fence_before_store(memory_order order) BOOST_NOEXCEPT
{ {
platform_fence_before(order); platform_fence_before(order);
} }
inline void inline void
platform_fence_after_store(memory_order order) platform_fence_after_store(memory_order order) BOOST_NOEXCEPT
{ {
if (order == memory_order_seq_cst) if (order == memory_order_seq_cst)
arm_barrier(); arm_barrier();
} }
inline void inline void
platform_fence_after_load(memory_order order) platform_fence_after_load(memory_order order) BOOST_NOEXCEPT
{ {
platform_fence_after(order); platform_fence_after(order);
} }
template<typename T> template<typename T>
inline bool inline bool
platform_cmpxchg32(T & expected, T desired, volatile T * ptr) platform_cmpxchg32(T & expected, T desired, volatile T * ptr) BOOST_NOEXCEPT
{ {
int success; int success;
int tmp; int tmp;
__asm__ ( __asm__ __volatile__
(
BOOST_ATOMIC_ARM_ASM_START(%2) BOOST_ATOMIC_ARM_ASM_START(%2)
"mov %1, #0\n" // success = 0 "mov %1, #0\n" // success = 0
"ldrex %0, %3\n" // expected' = *(&i) "ldrex %0, %3\n" // expected' = *(&i)
@ -175,7 +175,8 @@ platform_cmpxchg32(T & expected, T desired, volatile T * ptr)
inline void inline void
atomic_thread_fence(memory_order order) atomic_thread_fence(memory_order order)
{ {
switch(order) { switch(order)
{
case memory_order_acquire: case memory_order_acquire:
case memory_order_release: case memory_order_release:
case memory_order_acq_rel: case memory_order_acq_rel:
@ -195,9 +196,8 @@ atomic_signal_fence(memory_order)
class atomic_flag class atomic_flag
{ {
private: private:
atomic_flag(const atomic_flag &) /* = delete */ ;
atomic_flag & operator=(const atomic_flag &) /* = delete */ ;
uint32_t v_; uint32_t v_;
public: public:
BOOST_CONSTEXPR atomic_flag(void) BOOST_NOEXCEPT : v_(0) {} BOOST_CONSTEXPR atomic_flag(void) BOOST_NOEXCEPT : v_(0) {}
@ -221,7 +221,11 @@ public:
atomics::detail::platform_fence_after(order); atomics::detail::platform_fence_after(order);
return expected; return expected;
} }
BOOST_DELETED_FUNCTION(atomic_flag(const atomic_flag &))
BOOST_DELETED_FUNCTION(atomic_flag& operator=(const atomic_flag &))
}; };
#define BOOST_ATOMIC_FLAG_LOCK_FREE 2 #define BOOST_ATOMIC_FLAG_LOCK_FREE 2
} }
@ -249,4 +253,3 @@ public:
#endif /* !defined(BOOST_ATOMIC_FORCE_FALLBACK) */ #endif /* !defined(BOOST_ATOMIC_FORCE_FALLBACK) */
#endif #endif

File diff suppressed because it is too large Load Diff

View File

@ -11,11 +11,10 @@
#ifndef BOOST_ATOMIC_DETAIL_GENERIC_CAS_HPP #ifndef BOOST_ATOMIC_DETAIL_GENERIC_CAS_HPP
#define BOOST_ATOMIC_DETAIL_GENERIC_CAS_HPP #define BOOST_ATOMIC_DETAIL_GENERIC_CAS_HPP
#include <cstddef>
#include <boost/cstdint.hpp> #include <boost/cstdint.hpp>
#include <boost/atomic/detail/config.hpp> #include <boost/atomic/detail/config.hpp>
#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE #ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once #pragma once
#endif #endif
@ -25,7 +24,8 @@ namespace boost {
inline void inline void
atomic_thread_fence(memory_order order) atomic_thread_fence(memory_order order)
{ {
switch(order) { switch(order)
{
case memory_order_relaxed: case memory_order_relaxed:
break; break;
case memory_order_release: case memory_order_release:
@ -56,7 +56,8 @@ platform_fence_after(memory_order)
inline void inline void
platform_fence_before_store(memory_order order) platform_fence_before_store(memory_order order)
{ {
switch(order) { switch(order)
{
case memory_order_relaxed: case memory_order_relaxed:
case memory_order_acquire: case memory_order_acquire:
case memory_order_consume: case memory_order_consume:
@ -79,7 +80,8 @@ platform_fence_after_store(memory_order order)
inline void inline void
platform_fence_after_load(memory_order order) platform_fence_after_load(memory_order order)
{ {
switch(order) { switch(order)
{
case memory_order_relaxed: case memory_order_relaxed:
case memory_order_release: case memory_order_release:
break; break;
@ -132,6 +134,7 @@ public:
return expected; return expected;
} }
}; };
#define BOOST_ATOMIC_FLAG_LOCK_FREE 2 #define BOOST_ATOMIC_FLAG_LOCK_FREE 2
} }

View File

@ -8,11 +8,12 @@
// See accompanying file LICENSE_1_0.txt or copy at // See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt) // http://www.boost.org/LICENSE_1_0.txt)
#include <string.h>
#include <cstddef> #include <cstddef>
#include <boost/cstdint.hpp> #include <boost/cstdint.hpp>
#include <boost/atomic/detail/config.hpp> #include <boost/atomic/detail/config.hpp>
#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE #ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once #pragma once
#endif #endif
@ -65,7 +66,8 @@ namespace detail {
inline void inline void
ppc_fence_before(memory_order order) ppc_fence_before(memory_order order)
{ {
switch(order) { switch(order)
{
case memory_order_release: case memory_order_release:
case memory_order_acq_rel: case memory_order_acq_rel:
#if defined(__powerpc64__) #if defined(__powerpc64__)
@ -81,7 +83,8 @@ ppc_fence_before(memory_order order)
inline void inline void
ppc_fence_after(memory_order order) ppc_fence_after(memory_order order)
{ {
switch(order) { switch(order)
{
case memory_order_acquire: case memory_order_acquire:
case memory_order_acq_rel: case memory_order_acq_rel:
case memory_order_seq_cst: case memory_order_seq_cst:
@ -95,7 +98,8 @@ ppc_fence_after(memory_order order)
inline void inline void
ppc_fence_after_store(memory_order order) ppc_fence_after_store(memory_order order)
{ {
switch(order) { switch(order)
{
case memory_order_seq_cst: case memory_order_seq_cst:
__asm__ __volatile__ ("sync"); __asm__ __volatile__ ("sync");
default:; default:;
@ -199,13 +203,18 @@ namespace detail {
template<typename T> template<typename T>
class base_atomic<T, int, 1, true> class base_atomic<T, int, 1, true>
{ {
private:
typedef base_atomic this_type; typedef base_atomic this_type;
typedef T value_type; typedef T value_type;
typedef int32_t storage_type; typedef int32_t storage_type;
typedef T difference_type; typedef T difference_type;
protected:
typedef value_type value_arg_type;
public: public:
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
base_atomic(void) {}
void void
store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
@ -411,22 +420,29 @@ public:
} }
BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private: private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
storage_type v_; storage_type v_;
}; };
template<typename T> template<typename T>
class base_atomic<T, int, 1, false> class base_atomic<T, int, 1, false>
{ {
private:
typedef base_atomic this_type; typedef base_atomic this_type;
typedef T value_type; typedef T value_type;
typedef uint32_t storage_type; typedef uint32_t storage_type;
typedef T difference_type; typedef T difference_type;
protected:
typedef value_type value_arg_type;
public: public:
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
base_atomic(void) {}
void void
store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
@ -633,22 +649,29 @@ public:
} }
BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private: private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
storage_type v_; storage_type v_;
}; };
template<typename T> template<typename T>
class base_atomic<T, int, 2, true> class base_atomic<T, int, 2, true>
{ {
private:
typedef base_atomic this_type; typedef base_atomic this_type;
typedef T value_type; typedef T value_type;
typedef int32_t storage_type; typedef int32_t storage_type;
typedef T difference_type; typedef T difference_type;
protected:
typedef value_type value_arg_type;
public: public:
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
base_atomic(void) {}
void void
store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
@ -855,22 +878,29 @@ public:
} }
BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private: private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
storage_type v_; storage_type v_;
}; };
template<typename T> template<typename T>
class base_atomic<T, int, 2, false> class base_atomic<T, int, 2, false>
{ {
private:
typedef base_atomic this_type; typedef base_atomic this_type;
typedef T value_type; typedef T value_type;
typedef uint32_t storage_type; typedef uint32_t storage_type;
typedef T difference_type; typedef T difference_type;
protected:
typedef value_type value_arg_type;
public: public:
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
base_atomic(void) {}
void void
store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
@ -1077,21 +1107,28 @@ public:
} }
BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private: private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
storage_type v_; storage_type v_;
}; };
template<typename T, bool Sign> template<typename T, bool Sign>
class base_atomic<T, int, 4, Sign> class base_atomic<T, int, 4, Sign>
{ {
private:
typedef base_atomic this_type; typedef base_atomic this_type;
typedef T value_type; typedef T value_type;
typedef T difference_type; typedef T difference_type;
protected:
typedef value_type value_arg_type;
public: public:
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
base_atomic(void) {}
void void
store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
@ -1292,9 +1329,11 @@ public:
} }
BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private: private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
value_type v_; value_type v_;
}; };
@ -1303,12 +1342,17 @@ private:
template<typename T, bool Sign> template<typename T, bool Sign>
class base_atomic<T, int, 8, Sign> class base_atomic<T, int, 8, Sign>
{ {
private:
typedef base_atomic this_type; typedef base_atomic this_type;
typedef T value_type; typedef T value_type;
typedef T difference_type; typedef T difference_type;
protected:
typedef value_type value_arg_type;
public: public:
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
base_atomic(void) {}
void void
store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
@ -1509,9 +1553,11 @@ public:
} }
BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private: private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
value_type v_; value_type v_;
}; };
@ -1524,12 +1570,17 @@ private:
template<bool Sign> template<bool Sign>
class base_atomic<void *, void *, 4, Sign> class base_atomic<void *, void *, 4, Sign>
{ {
private:
typedef base_atomic this_type; typedef base_atomic this_type;
typedef ptrdiff_t difference_type; typedef std::ptrdiff_t difference_type;
typedef void * value_type; typedef void * value_type;
protected:
typedef value_type value_arg_type;
public: public:
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
base_atomic(void) {}
void void
store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
@ -1681,21 +1732,28 @@ public:
} }
BOOST_ATOMIC_DECLARE_VOID_POINTER_OPERATORS BOOST_ATOMIC_DECLARE_VOID_POINTER_OPERATORS
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private: private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
value_type v_; value_type v_;
}; };
template<typename T, bool Sign> template<typename T, bool Sign>
class base_atomic<T *, void *, 4, Sign> class base_atomic<T *, void *, 4, Sign>
{ {
private:
typedef base_atomic this_type; typedef base_atomic this_type;
typedef T * value_type; typedef T * value_type;
typedef ptrdiff_t difference_type; typedef std::ptrdiff_t difference_type;
protected:
typedef value_type value_arg_type;
public: public:
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
base_atomic(void) {}
void void
store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
@ -1849,9 +1907,11 @@ public:
} }
BOOST_ATOMIC_DECLARE_POINTER_OPERATORS BOOST_ATOMIC_DECLARE_POINTER_OPERATORS
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private: private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
value_type v_; value_type v_;
}; };
@ -1860,12 +1920,17 @@ private:
template<bool Sign> template<bool Sign>
class base_atomic<void *, void *, 8, Sign> class base_atomic<void *, void *, 8, Sign>
{ {
private:
typedef base_atomic this_type; typedef base_atomic this_type;
typedef ptrdiff_t difference_type; typedef std::ptrdiff_t difference_type;
typedef void * value_type; typedef void * value_type;
protected:
typedef value_type value_arg_type;
public: public:
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
base_atomic(void) {}
void void
store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
@ -2017,21 +2082,28 @@ public:
} }
BOOST_ATOMIC_DECLARE_VOID_POINTER_OPERATORS BOOST_ATOMIC_DECLARE_VOID_POINTER_OPERATORS
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private: private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
value_type v_; value_type v_;
}; };
template<typename T, bool Sign> template<typename T, bool Sign>
class base_atomic<T *, void *, 8, Sign> class base_atomic<T *, void *, 8, Sign>
{ {
private:
typedef base_atomic this_type; typedef base_atomic this_type;
typedef T * value_type; typedef T * value_type;
typedef ptrdiff_t difference_type; typedef std::ptrdiff_t difference_type;
protected:
typedef value_type value_arg_type;
public: public:
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
base_atomic(void) {}
void void
store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
@ -2185,9 +2257,11 @@ public:
} }
BOOST_ATOMIC_DECLARE_POINTER_OPERATORS BOOST_ATOMIC_DECLARE_POINTER_OPERATORS
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private: private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
value_type v_; value_type v_;
}; };
@ -2198,15 +2272,20 @@ private:
template<typename T, bool Sign> template<typename T, bool Sign>
class base_atomic<T, void, 1, Sign> class base_atomic<T, void, 1, Sign>
{ {
private:
typedef base_atomic this_type; typedef base_atomic this_type;
typedef T value_type; typedef T value_type;
typedef uint32_t storage_type; typedef uint32_t storage_type;
protected:
typedef value_type const& value_arg_type;
public: public:
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0)
{ {
memcpy(&v_, &v, sizeof(value_type)); memcpy(&v_, &v, sizeof(value_type));
} }
base_atomic(void) {}
void void
store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
@ -2340,26 +2419,32 @@ public:
} }
BOOST_ATOMIC_DECLARE_BASE_OPERATORS BOOST_ATOMIC_DECLARE_BASE_OPERATORS
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private: private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
storage_type v_; storage_type v_;
}; };
template<typename T, bool Sign> template<typename T, bool Sign>
class base_atomic<T, void, 2, Sign> class base_atomic<T, void, 2, Sign>
{ {
private:
typedef base_atomic this_type; typedef base_atomic this_type;
typedef T value_type; typedef T value_type;
typedef uint32_t storage_type; typedef uint32_t storage_type;
protected:
typedef value_type const& value_arg_type;
public: public:
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0)
{ {
memcpy(&v_, &v, sizeof(value_type)); memcpy(&v_, &v, sizeof(value_type));
} }
base_atomic(void) {}
void void
store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
{ {
@ -2492,26 +2577,32 @@ public:
} }
BOOST_ATOMIC_DECLARE_BASE_OPERATORS BOOST_ATOMIC_DECLARE_BASE_OPERATORS
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private: private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
storage_type v_; storage_type v_;
}; };
template<typename T, bool Sign> template<typename T, bool Sign>
class base_atomic<T, void, 4, Sign> class base_atomic<T, void, 4, Sign>
{ {
private:
typedef base_atomic this_type; typedef base_atomic this_type;
typedef T value_type; typedef T value_type;
typedef uint32_t storage_type; typedef uint32_t storage_type;
protected:
typedef value_type const& value_arg_type;
public: public:
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0)
{ {
memcpy(&v_, &v, sizeof(value_type)); memcpy(&v_, &v, sizeof(value_type));
} }
base_atomic(void) {}
void void
store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
{ {
@ -2644,9 +2735,11 @@ public:
} }
BOOST_ATOMIC_DECLARE_BASE_OPERATORS BOOST_ATOMIC_DECLARE_BASE_OPERATORS
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private: private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
storage_type v_; storage_type v_;
}; };
@ -2655,17 +2748,21 @@ private:
template<typename T, bool Sign> template<typename T, bool Sign>
class base_atomic<T, void, 8, Sign> class base_atomic<T, void, 8, Sign>
{ {
private:
typedef base_atomic this_type; typedef base_atomic this_type;
typedef T value_type; typedef T value_type;
typedef uint64_t storage_type; typedef uint64_t storage_type;
protected:
typedef value_type const& value_arg_type;
public: public:
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0)
{ {
memcpy(&v_, &v, sizeof(value_type)); memcpy(&v_, &v, sizeof(value_type));
} }
base_atomic(void) {}
void void
store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
{ {
@ -2798,11 +2895,14 @@ public:
} }
BOOST_ATOMIC_DECLARE_BASE_OPERATORS BOOST_ATOMIC_DECLARE_BASE_OPERATORS
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private: private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
storage_type v_; storage_type v_;
}; };
#endif #endif
} }
@ -2812,7 +2912,8 @@ private:
inline void inline void
atomic_thread_fence(memory_order order) atomic_thread_fence(memory_order order)
{ {
switch(order) { switch(order)
{
case memory_order_acquire: case memory_order_acquire:
__asm__ __volatile__ ("isync" ::: "memory"); __asm__ __volatile__ ("isync" ::: "memory");
break; break;
@ -2832,7 +2933,8 @@ atomic_thread_fence(memory_order order)
inline void inline void
atomic_signal_fence(memory_order order) atomic_signal_fence(memory_order order)
{ {
switch(order) { switch(order)
{
case memory_order_acquire: case memory_order_acquire:
case memory_order_release: case memory_order_release:
case memory_order_acq_rel: case memory_order_acq_rel:

View File

@ -8,11 +8,12 @@
// See accompanying file LICENSE_1_0.txt or copy at // See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt) // http://www.boost.org/LICENSE_1_0.txt)
#include <string.h>
#include <cstddef> #include <cstddef>
#include <boost/cstdint.hpp> #include <boost/cstdint.hpp>
#include <boost/atomic/detail/config.hpp> #include <boost/atomic/detail/config.hpp>
#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE #ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once #pragma once
#endif #endif
@ -23,7 +24,8 @@ namespace detail {
inline void inline void
platform_fence_before(memory_order order) platform_fence_before(memory_order order)
{ {
switch(order) { switch(order)
{
case memory_order_relaxed: case memory_order_relaxed:
case memory_order_acquire: case memory_order_acquire:
case memory_order_consume: case memory_order_consume:
@ -43,7 +45,8 @@ platform_fence_before(memory_order order)
inline void inline void
platform_fence_after(memory_order order) platform_fence_after(memory_order order)
{ {
switch(order) { switch(order)
{
case memory_order_relaxed: case memory_order_relaxed:
case memory_order_release: case memory_order_release:
break; break;
@ -66,7 +69,8 @@ platform_fence_after(memory_order order)
inline void inline void
platform_fence_after_store(memory_order order) platform_fence_after_store(memory_order order)
{ {
switch(order) { switch(order)
{
case memory_order_seq_cst: case memory_order_seq_cst:
__asm__ __volatile__ ("membar #Sync" ::: "memory"); __asm__ __volatile__ ("membar #Sync" ::: "memory");
default:; default:;
@ -141,7 +145,8 @@ namespace boost {
inline void inline void
atomic_thread_fence(memory_order order) atomic_thread_fence(memory_order order)
{ {
switch(order) { switch(order)
{
case memory_order_relaxed: case memory_order_relaxed:
break; break;
case memory_order_release: case memory_order_release:
@ -177,13 +182,18 @@ namespace detail {
template<typename T> template<typename T>
class base_atomic<T, int, 1, true> class base_atomic<T, int, 1, true>
{ {
private:
typedef base_atomic this_type; typedef base_atomic this_type;
typedef T value_type; typedef T value_type;
typedef T difference_type; typedef T difference_type;
typedef int32_t storage_type; typedef int32_t storage_type;
protected:
typedef value_type value_arg_type;
public: public:
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
base_atomic(void) {}
void void
store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
@ -291,22 +301,29 @@ public:
} }
BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private: private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
storage_type v_; storage_type v_;
}; };
template<typename T> template<typename T>
class base_atomic<T, int, 1, false> class base_atomic<T, int, 1, false>
{ {
private:
typedef base_atomic this_type; typedef base_atomic this_type;
typedef T value_type; typedef T value_type;
typedef T difference_type; typedef T difference_type;
typedef uint32_t storage_type; typedef uint32_t storage_type;
protected:
typedef value_type value_arg_type;
public: public:
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
base_atomic(void) {}
void void
store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
@ -414,22 +431,29 @@ public:
} }
BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private: private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
storage_type v_; storage_type v_;
}; };
template<typename T> template<typename T>
class base_atomic<T, int, 2, true> class base_atomic<T, int, 2, true>
{ {
private:
typedef base_atomic this_type; typedef base_atomic this_type;
typedef T value_type; typedef T value_type;
typedef T difference_type; typedef T difference_type;
typedef int32_t storage_type; typedef int32_t storage_type;
protected:
typedef value_type value_arg_type;
public: public:
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
base_atomic(void) {}
void void
store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
@ -537,22 +561,29 @@ public:
} }
BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private: private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
storage_type v_; storage_type v_;
}; };
template<typename T> template<typename T>
class base_atomic<T, int, 2, false> class base_atomic<T, int, 2, false>
{ {
private:
typedef base_atomic this_type; typedef base_atomic this_type;
typedef T value_type; typedef T value_type;
typedef T difference_type; typedef T difference_type;
typedef uint32_t storage_type; typedef uint32_t storage_type;
protected:
typedef value_type value_arg_type;
public: public:
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
base_atomic(void) {}
void void
store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
@ -660,21 +691,28 @@ public:
} }
BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private: private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
storage_type v_; storage_type v_;
}; };
template<typename T, bool Sign> template<typename T, bool Sign>
class base_atomic<T, int, 4, Sign> class base_atomic<T, int, 4, Sign>
{ {
private:
typedef base_atomic this_type; typedef base_atomic this_type;
typedef T value_type; typedef T value_type;
typedef T difference_type; typedef T difference_type;
protected:
typedef value_type value_arg_type;
public: public:
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
base_atomic(void) {}
void void
store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
@ -780,9 +818,11 @@ public:
} }
BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private: private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
value_type v_; value_type v_;
}; };
@ -791,12 +831,17 @@ private:
template<bool Sign> template<bool Sign>
class base_atomic<void *, void *, 4, Sign> class base_atomic<void *, void *, 4, Sign>
{ {
private:
typedef base_atomic this_type; typedef base_atomic this_type;
typedef ptrdiff_t difference_type; typedef std::ptrdiff_t difference_type;
typedef void * value_type; typedef void * value_type;
protected:
typedef value_type value_arg_type;
public: public:
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
base_atomic(void) {}
void void
store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
@ -876,21 +921,27 @@ public:
BOOST_ATOMIC_DECLARE_VOID_POINTER_OPERATORS BOOST_ATOMIC_DECLARE_VOID_POINTER_OPERATORS
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private: private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
value_type v_; value_type v_;
}; };
template<typename T, bool Sign> template<typename T, bool Sign>
class base_atomic<T *, void *, 4, Sign> class base_atomic<T *, void *, 4, Sign>
{ {
private:
typedef base_atomic this_type; typedef base_atomic this_type;
typedef T * value_type; typedef T * value_type;
typedef ptrdiff_t difference_type; typedef std::ptrdiff_t difference_type;
protected:
typedef value_type value_arg_type;
public: public:
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {} BOOST_CONSTEXPR explicit base_atomic(value_type v) BOOST_NOEXCEPT : v_(v) {}
base_atomic(void) {}
void void
store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT store(value_type v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
@ -972,9 +1023,11 @@ public:
} }
BOOST_ATOMIC_DECLARE_POINTER_OPERATORS BOOST_ATOMIC_DECLARE_POINTER_OPERATORS
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private: private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
value_type v_; value_type v_;
}; };
@ -983,15 +1036,20 @@ private:
template<typename T, bool Sign> template<typename T, bool Sign>
class base_atomic<T, void, 1, Sign> class base_atomic<T, void, 1, Sign>
{ {
private:
typedef base_atomic this_type; typedef base_atomic this_type;
typedef T value_type; typedef T value_type;
typedef uint32_t storage_type; typedef uint32_t storage_type;
protected:
typedef value_type const& value_arg_type;
public: public:
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
BOOST_CONSTEXPR explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) BOOST_CONSTEXPR explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0)
{ {
memcpy(&v_, &v, sizeof(value_type)); memcpy(&v_, &v, sizeof(value_type));
} }
base_atomic(void) {}
void void
store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
@ -1064,24 +1122,31 @@ public:
} }
BOOST_ATOMIC_DECLARE_BASE_OPERATORS BOOST_ATOMIC_DECLARE_BASE_OPERATORS
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private: private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
storage_type v_; storage_type v_;
}; };
template<typename T, bool Sign> template<typename T, bool Sign>
class base_atomic<T, void, 2, Sign> class base_atomic<T, void, 2, Sign>
{ {
private:
typedef base_atomic this_type; typedef base_atomic this_type;
typedef T value_type; typedef T value_type;
typedef uint32_t storage_type; typedef uint32_t storage_type;
protected:
typedef value_type const& value_arg_type;
public: public:
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
BOOST_CONSTEXPR explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) BOOST_CONSTEXPR explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0)
{ {
memcpy(&v_, &v, sizeof(value_type)); memcpy(&v_, &v, sizeof(value_type));
} }
base_atomic(void) {}
void void
store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
@ -1154,24 +1219,31 @@ public:
} }
BOOST_ATOMIC_DECLARE_BASE_OPERATORS BOOST_ATOMIC_DECLARE_BASE_OPERATORS
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private: private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
storage_type v_; storage_type v_;
}; };
template<typename T, bool Sign> template<typename T, bool Sign>
class base_atomic<T, void, 4, Sign> class base_atomic<T, void, 4, Sign>
{ {
private:
typedef base_atomic this_type; typedef base_atomic this_type;
typedef T value_type; typedef T value_type;
typedef uint32_t storage_type; typedef uint32_t storage_type;
protected:
typedef value_type const& value_arg_type;
public: public:
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
BOOST_CONSTEXPR explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0) BOOST_CONSTEXPR explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0)
{ {
memcpy(&v_, &v, sizeof(value_type)); memcpy(&v_, &v, sizeof(value_type));
} }
base_atomic(void) {}
void void
store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT store(value_type const& v, memory_order order = memory_order_seq_cst) volatile BOOST_NOEXCEPT
@ -1244,9 +1316,11 @@ public:
} }
BOOST_ATOMIC_DECLARE_BASE_OPERATORS BOOST_ATOMIC_DECLARE_BASE_OPERATORS
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private: private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
storage_type v_; storage_type v_;
}; };

File diff suppressed because it is too large Load Diff

View File

@ -14,7 +14,7 @@
#include <boost/atomic/detail/base.hpp> #include <boost/atomic/detail/base.hpp>
#include <boost/atomic/detail/builder.hpp> #include <boost/atomic/detail/builder.hpp>
#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE #ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once #pragma once
#endif #endif

View File

@ -10,7 +10,7 @@
#include <boost/atomic/detail/config.hpp> #include <boost/atomic/detail/config.hpp>
#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE #ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once #pragma once
#endif #endif
@ -43,6 +43,11 @@
#define BOOST_ATOMIC_INTERLOCKED_OR(dest, arg) _InterlockedOr((long*)(dest), (long)(arg)) #define BOOST_ATOMIC_INTERLOCKED_OR(dest, arg) _InterlockedOr((long*)(dest), (long)(arg))
#define BOOST_ATOMIC_INTERLOCKED_XOR(dest, arg) _InterlockedXor((long*)(dest), (long)(arg)) #define BOOST_ATOMIC_INTERLOCKED_XOR(dest, arg) _InterlockedXor((long*)(dest), (long)(arg))
#if (defined(_M_IX86) && _M_IX86 >= 500) || defined(_M_AMD64) || defined(_M_IA64)
#pragma intrinsic(_InterlockedCompareExchange64)
#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE64(dest, exchange, compare) _InterlockedCompareExchange64((__int64*)(dest), (__int64)(exchange), (__int64)(compare))
#endif
#if _MSC_VER >= 1600 #if _MSC_VER >= 1600
// MSVC 2010 and later provide intrinsics for 8 and 16 bit integers. // MSVC 2010 and later provide intrinsics for 8 and 16 bit integers.
@ -81,14 +86,12 @@
#if defined(_M_AMD64) || defined(_M_IA64) #if defined(_M_AMD64) || defined(_M_IA64)
#pragma intrinsic(_InterlockedCompareExchange64)
#pragma intrinsic(_InterlockedExchangeAdd64) #pragma intrinsic(_InterlockedExchangeAdd64)
#pragma intrinsic(_InterlockedExchange64) #pragma intrinsic(_InterlockedExchange64)
#pragma intrinsic(_InterlockedAnd64) #pragma intrinsic(_InterlockedAnd64)
#pragma intrinsic(_InterlockedOr64) #pragma intrinsic(_InterlockedOr64)
#pragma intrinsic(_InterlockedXor64) #pragma intrinsic(_InterlockedXor64)
#define BOOST_ATOMIC_INTERLOCKED_COMPARE_EXCHANGE64(dest, exchange, compare) _InterlockedCompareExchange64((__int64*)(dest), (__int64)(exchange), (__int64)(compare))
#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64(dest, addend) _InterlockedExchangeAdd64((__int64*)(dest), (__int64)(addend)) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE_ADD64(dest, addend) _InterlockedExchangeAdd64((__int64*)(dest), (__int64)(addend))
#define BOOST_ATOMIC_INTERLOCKED_EXCHANGE64(dest, newval) _InterlockedExchange64((__int64*)(dest), (__int64)(newval)) #define BOOST_ATOMIC_INTERLOCKED_EXCHANGE64(dest, newval) _InterlockedExchange64((__int64*)(dest), (__int64)(newval))
#define BOOST_ATOMIC_INTERLOCKED_AND64(dest, arg) _InterlockedAnd64((__int64*)(dest), (__int64)(arg)) #define BOOST_ATOMIC_INTERLOCKED_AND64(dest, arg) _InterlockedAnd64((__int64*)(dest), (__int64)(arg))

View File

@ -0,0 +1,50 @@
#ifndef BOOST_ATOMIC_DETAIL_LINK_HPP
#define BOOST_ATOMIC_DETAIL_LINK_HPP
// Copyright (c) 2012 Hartmut Kaiser
//
// 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)
#include <boost/atomic/detail/config.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
///////////////////////////////////////////////////////////////////////////////
// Set up dll import/export options
#if (defined(BOOST_ATOMIC_DYN_LINK) || defined(BOOST_ALL_DYN_LINK)) && \
!defined(BOOST_ATOMIC_STATIC_LINK)
#if defined(BOOST_ATOMIC_SOURCE)
#define BOOST_ATOMIC_DECL BOOST_SYMBOL_EXPORT
#define BOOST_ATOMIC_BUILD_DLL
#else
#define BOOST_ATOMIC_DECL BOOST_SYMBOL_IMPORT
#endif
#endif // building a shared library
#ifndef BOOST_ATOMIC_DECL
#define BOOST_ATOMIC_DECL
#endif
///////////////////////////////////////////////////////////////////////////////
// Auto library naming
#if !defined(BOOST_ATOMIC_SOURCE) && !defined(BOOST_ALL_NO_LIB) && \
!defined(BOOST_ATOMIC_NO_LIB)
#define BOOST_LIB_NAME boost_atomic
// tell the auto-link code to select a dll when required:
#if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_ATOMIC_DYN_LINK)
#define BOOST_DYN_LINK
#endif
#include <boost/config/auto_link.hpp>
#endif // auto-linking disabled
#endif

View File

@ -36,7 +36,7 @@
#include <boost/memory_order.hpp> #include <boost/memory_order.hpp>
#include <boost/atomic/detail/config.hpp> #include <boost/atomic/detail/config.hpp>
#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE #ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once #pragma once
#endif #endif
@ -163,6 +163,7 @@ public:
return expected; return expected;
} }
}; };
#define BOOST_ATOMIC_FLAG_LOCK_FREE 2 #define BOOST_ATOMIC_FLAG_LOCK_FREE 2
} }

View File

@ -8,11 +8,12 @@
// http://www.boost.org/LICENSE_1_0.txt) // http://www.boost.org/LICENSE_1_0.txt)
#include <boost/atomic/detail/config.hpp> #include <boost/atomic/detail/config.hpp>
#include <boost/atomic/detail/link.hpp>
#ifndef BOOST_ATOMIC_FLAG_LOCK_FREE #ifndef BOOST_ATOMIC_FLAG_LOCK_FREE
#include <boost/thread/mutex.hpp> #include <boost/smart_ptr/detail/lightweight_mutex.hpp>
#endif #endif
#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE #ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once #pragma once
#endif #endif
@ -25,25 +26,19 @@ namespace detail {
class lockpool class lockpool
{ {
public: public:
typedef mutex lock_type; typedef boost::detail::lightweight_mutex lock_type;
class scoped_lock class scoped_lock :
public lock_type::scoped_lock
{ {
private: typedef lock_type::scoped_lock base_type;
lock_type& mtx_;
scoped_lock(scoped_lock const&) /* = delete */;
scoped_lock& operator=(scoped_lock const&) /* = delete */;
public: public:
explicit explicit scoped_lock(const volatile void * addr) : base_type(get_lock_for(addr))
scoped_lock(const volatile void * addr) : mtx_(get_lock_for(addr))
{ {
mtx_.lock();
}
~scoped_lock()
{
mtx_.unlock();
} }
BOOST_DELETED_FUNCTION(scoped_lock(scoped_lock const&))
BOOST_DELETED_FUNCTION(scoped_lock& operator=(scoped_lock const&))
}; };
private: private:
@ -61,10 +56,6 @@ public:
{ {
private: private:
atomic_flag& flag_; atomic_flag& flag_;
uint8_t padding[128 - sizeof(atomic_flag)];
scoped_lock(const scoped_lock &) /* = delete */;
scoped_lock& operator=(const scoped_lock &) /* = delete */;
public: public:
explicit explicit
@ -82,6 +73,9 @@ public:
{ {
flag_.clear(memory_order_release); flag_.clear(memory_order_release);
} }
BOOST_DELETED_FUNCTION(scoped_lock(const scoped_lock &))
BOOST_DELETED_FUNCTION(scoped_lock& operator=(const scoped_lock &))
}; };
private: private:

View File

@ -11,11 +11,17 @@
#include <boost/atomic/detail/config.hpp> #include <boost/atomic/detail/config.hpp>
#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE #ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once #pragma once
#endif #endif
#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) // Intel compiler does not support __atomic* intrinsics properly, although defines them (tested with 13.0.1 and 13.1.1 on Linux)
#if (defined(__GNUC__) && ((__GNUC__ * 100 + __GNUC_MINOR__) >= 407) && !defined(BOOST_INTEL_CXX_VERSION))\
|| (defined(BOOST_CLANG) && ((__clang_major__ * 100 + __clang_minor__) >= 302))
#include <boost/atomic/detail/gcc-atomic.hpp>
#elif defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
#include <boost/atomic/detail/gcc-x86.hpp> #include <boost/atomic/detail/gcc-x86.hpp>
@ -32,7 +38,10 @@
// I don't know how complete it is. // I don't know how complete it is.
#elif defined(__GNUC__) && (defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \ #elif defined(__GNUC__) && (defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \
|| defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) \ || defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) \
|| defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_7A__)) || defined(__ARM_ARCH_6K__) \
|| defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \
|| defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) \
|| defined(__ARM_ARCH_7EM__) || defined(__ARM_ARCH_7S__))
#include <boost/atomic/detail/gcc-armv6plus.hpp> #include <boost/atomic/detail/gcc-armv6plus.hpp>

View File

@ -10,7 +10,7 @@
#include <boost/atomic/detail/config.hpp> #include <boost/atomic/detail/config.hpp>
#include <boost/type_traits/is_integral.hpp> #include <boost/type_traits/is_integral.hpp>
#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE #ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once #pragma once
#endif #endif
@ -36,7 +36,7 @@ struct storage_size_of
enum _ enum _
{ {
size = sizeof(T), size = sizeof(T),
value = (size == 3 ? 4 : (size == 5 || size == 6 || size == 7 ? 8 : size)) value = (size == 3 ? 4 : (size >= 5 && size <= 7 ? 8 : (size >= 9 && size <= 15 ? 16 : size)))
}; };
}; };

File diff suppressed because it is too large Load Diff

View File

@ -12,9 +12,9 @@
#ifndef BOOST_CHRONO_DETAIL_INLINED_WIN_CHRONO_HPP #ifndef BOOST_CHRONO_DETAIL_INLINED_WIN_CHRONO_HPP
#define BOOST_CHRONO_DETAIL_INLINED_WIN_CHRONO_HPP #define BOOST_CHRONO_DETAIL_INLINED_WIN_CHRONO_HPP
#include <boost/detail/win/time.hpp> #include <boost/detail/winapi/time.hpp>
#include <boost/detail/win/timers.hpp> #include <boost/detail/winapi/timers.hpp>
#include <boost/detail/win/GetLastError.hpp> #include <boost/detail/winapi/GetLastError.hpp>
namespace boost namespace boost
{ {
@ -25,8 +25,8 @@ namespace chrono_detail
BOOST_CHRONO_INLINE double get_nanosecs_per_tic() BOOST_NOEXCEPT BOOST_CHRONO_INLINE double get_nanosecs_per_tic() BOOST_NOEXCEPT
{ {
boost::detail::win32::LARGE_INTEGER_ freq; boost::detail::winapi::LARGE_INTEGER_ freq;
if ( !boost::detail::win32::QueryPerformanceFrequency( &freq ) ) if ( !boost::detail::winapi::QueryPerformanceFrequency( &freq ) )
return 0.0L; return 0.0L;
return double(1000000000.0L / freq.QuadPart); return double(1000000000.0L / freq.QuadPart);
} }
@ -37,9 +37,9 @@ namespace chrono_detail
{ {
static double nanosecs_per_tic = chrono_detail::get_nanosecs_per_tic(); static double nanosecs_per_tic = chrono_detail::get_nanosecs_per_tic();
boost::detail::win32::LARGE_INTEGER_ pcount; boost::detail::winapi::LARGE_INTEGER_ pcount;
if ( (nanosecs_per_tic <= 0.0L) || if ( (nanosecs_per_tic <= 0.0L) ||
(!boost::detail::win32::QueryPerformanceCounter( &pcount )) ) (!boost::detail::winapi::QueryPerformanceCounter( &pcount )) )
{ {
BOOST_ASSERT(0 && "Boost::Chrono - Internal Error"); BOOST_ASSERT(0 && "Boost::Chrono - Internal Error");
return steady_clock::time_point(); return steady_clock::time_point();
@ -55,14 +55,14 @@ namespace chrono_detail
{ {
static double nanosecs_per_tic = chrono_detail::get_nanosecs_per_tic(); static double nanosecs_per_tic = chrono_detail::get_nanosecs_per_tic();
boost::detail::win32::LARGE_INTEGER_ pcount; boost::detail::winapi::LARGE_INTEGER_ pcount;
if ( (nanosecs_per_tic <= 0.0L) if ( (nanosecs_per_tic <= 0.0L)
|| (!boost::detail::win32::QueryPerformanceCounter( &pcount )) ) || (!boost::detail::winapi::QueryPerformanceCounter( &pcount )) )
{ {
boost::detail::win32::DWORD_ cause = boost::detail::winapi::DWORD_ cause =
((nanosecs_per_tic <= 0.0L) ((nanosecs_per_tic <= 0.0L)
? ERROR_NOT_SUPPORTED ? ERROR_NOT_SUPPORTED
: boost::detail::win32::GetLastError()); : boost::detail::winapi::GetLastError());
if (BOOST_CHRONO_IS_THROWS(ec)) { if (BOOST_CHRONO_IS_THROWS(ec)) {
boost::throw_exception( boost::throw_exception(
system::system_error( system::system_error(
@ -89,15 +89,8 @@ namespace chrono_detail
BOOST_CHRONO_INLINE BOOST_CHRONO_INLINE
system_clock::time_point system_clock::now() BOOST_NOEXCEPT system_clock::time_point system_clock::now() BOOST_NOEXCEPT
{ {
boost::detail::win32::FILETIME_ ft; boost::detail::winapi::FILETIME_ ft;
#if defined(UNDER_CE) boost::detail::winapi::GetSystemTimeAsFileTime( &ft ); // never fails
// Windows CE does not define GetSystemTimeAsFileTime so we do it in two steps.
boost::detail::win32::SYSTEMTIME_ st;
boost::detail::win32::GetSystemTime( &st );
boost::detail::win32::SystemTimeToFileTime( &st, &ft );
#else
boost::detail::win32::GetSystemTimeAsFileTime( &ft ); // never fails
#endif
return system_clock::time_point( return system_clock::time_point(
system_clock::duration( system_clock::duration(
((static_cast<__int64>( ft.dwHighDateTime ) << 32) | ft.dwLowDateTime) ((static_cast<__int64>( ft.dwHighDateTime ) << 32) | ft.dwLowDateTime)
@ -110,21 +103,17 @@ namespace chrono_detail
BOOST_CHRONO_INLINE BOOST_CHRONO_INLINE
system_clock::time_point system_clock::now( system::error_code & ec ) system_clock::time_point system_clock::now( system::error_code & ec )
{ {
boost::detail::win32::FILETIME_ ft; boost::detail::winapi::FILETIME_ ft;
#if defined(UNDER_CE) boost::detail::winapi::GetSystemTimeAsFileTime( &ft ); // never fails
// Windows CE does not define GetSystemTimeAsFileTime so we do it in two steps.
boost::detail::win32::SYSTEMTIME_ st;
boost::detail::win32::GetSystemTime( &st );
boost::detail::win32::SystemTimeToFileTime( &st, &ft );
#else
boost::detail::win32::GetSystemTimeAsFileTime( &ft ); // never fails
#endif
if (!BOOST_CHRONO_IS_THROWS(ec)) if (!BOOST_CHRONO_IS_THROWS(ec))
{ {
ec.clear(); ec.clear();
} }
return time_point(duration( return system_clock::time_point(
(static_cast<__int64>( ft.dwHighDateTime ) << 32) | ft.dwLowDateTime)); system_clock::duration(
((static_cast<__int64>( ft.dwHighDateTime ) << 32) | ft.dwLowDateTime)
-116444736000000000LL
));
} }
#endif #endif
@ -132,7 +121,6 @@ namespace chrono_detail
std::time_t system_clock::to_time_t(const system_clock::time_point& t) BOOST_NOEXCEPT std::time_t system_clock::to_time_t(const system_clock::time_point& t) BOOST_NOEXCEPT
{ {
__int64 temp = t.time_since_epoch().count(); __int64 temp = t.time_since_epoch().count();
temp /= 10000000; temp /= 10000000;
return static_cast<std::time_t>( temp ); return static_cast<std::time_t>( temp );
} }
@ -142,7 +130,6 @@ namespace chrono_detail
{ {
__int64 temp = t; __int64 temp = t;
temp *= 10000000; temp *= 10000000;
return time_point(duration(temp)); return time_point(duration(temp));
} }

File diff suppressed because it is too large Load Diff

View File

@ -15,9 +15,19 @@
#include <boost/iterator.hpp> #include <boost/iterator.hpp>
#include <boost/throw_exception.hpp> #include <boost/throw_exception.hpp>
#include <boost/move/move.hpp>
#include <boost/type_traits/is_nothrow_move_constructible.hpp>
#include <boost/detail/no_exceptions_support.hpp> #include <boost/detail/no_exceptions_support.hpp>
#include <iterator> #include <iterator>
// Silence MS /W4 warnings like C4913:
// "user defined binary operator ',' exists but no overload could convert all operands, default built-in binary operator ',' used"
// This might happen when previously including some boost headers that overload the coma operator.
#if defined(_MSC_VER)
# pragma warning(push)
# pragma warning(disable:4913)
#endif
namespace boost { namespace boost {
namespace cb_details { namespace cb_details {
@ -28,9 +38,11 @@ template<class ForwardIterator, class Diff, class T, class Alloc>
void uninitialized_fill_n_with_alloc( void uninitialized_fill_n_with_alloc(
ForwardIterator first, Diff n, const T& item, Alloc& alloc); ForwardIterator first, Diff n, const T& item, Alloc& alloc);
template<class InputIterator, class ForwardIterator, class Alloc> template<class ValueType, class InputIterator, class ForwardIterator>
ForwardIterator uninitialized_copy_with_alloc( ForwardIterator uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator dest);
InputIterator first, InputIterator last, ForwardIterator dest, Alloc& alloc);
template<class ValueType, class InputIterator, class ForwardIterator>
ForwardIterator uninitialized_move_if_noexcept(InputIterator first, InputIterator last, ForwardIterator dest);
/*! /*!
\struct const_traits \struct const_traits
@ -115,21 +127,25 @@ private:
\struct assign_range \struct assign_range
\brief Helper functor for assigning range of items. \brief Helper functor for assigning range of items.
*/ */
template <class Iterator, class Alloc> template <class ValueType, class Iterator>
struct assign_range { struct assign_range {
const Iterator& m_first; Iterator m_first;
const Iterator& m_last; Iterator m_last;
Alloc& m_alloc;
assign_range(const Iterator& first, const Iterator& last, Alloc& alloc) assign_range(const Iterator& first, const Iterator& last) BOOST_NOEXCEPT
: m_first(first), m_last(last), m_alloc(alloc) {} : m_first(first), m_last(last) {}
template <class Pointer> template <class Pointer>
void operator () (Pointer p) const { void operator () (Pointer p) const {
uninitialized_copy_with_alloc(m_first, m_last, p, m_alloc); boost::cb_details::uninitialized_copy<ValueType>(m_first, m_last, p);
} }
private:
assign_range<Iterator, Alloc>& operator = (const assign_range<Iterator, Alloc>&); // do not generate
}; };
template <class ValueType, class Iterator>
inline assign_range<ValueType, Iterator> make_assign_range(const Iterator& first, const Iterator& last) {
return assign_range<ValueType, Iterator>(first, last);
}
/*! /*!
\class capacity_control \class capacity_control
\brief Capacity controller of the space optimized circular buffer. \brief Capacity controller of the space optimized circular buffer.
@ -137,18 +153,19 @@ private:
template <class Size> template <class Size>
class capacity_control { class capacity_control {
//! The capacity of the space optimized circular buffer. //! The capacity of the space-optimized circular buffer.
Size m_capacity; Size m_capacity;
//! The lowest guaranteed capacity of the adapted circular buffer. //! The lowest guaranteed or minimum capacity of the adapted space-optimized circular buffer.
Size m_min_capacity; Size m_min_capacity;
public: public:
//! Constructor. //! Constructor.
capacity_control(Size buffer_capacity, Size min_buffer_capacity = 0) capacity_control(Size buffer_capacity, Size min_buffer_capacity = 0)
: m_capacity(buffer_capacity), m_min_capacity(min_buffer_capacity) { : m_capacity(buffer_capacity), m_min_capacity(min_buffer_capacity)
BOOST_CB_ASSERT(buffer_capacity >= min_buffer_capacity); // check for capacity lower than min_capacity { // Check for capacity lower than min_capacity.
BOOST_CB_ASSERT(buffer_capacity >= min_buffer_capacity);
} }
// Default copy constructor. // Default copy constructor.
@ -425,26 +442,53 @@ inline typename Traits::difference_type* distance_type(const iterator<Buff, Trai
#endif // #if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_MSVC_STD_ITERATOR) #endif // #if defined(BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION) && !defined(BOOST_MSVC_STD_ITERATOR)
/*! /*!
\fn ForwardIterator uninitialized_copy_with_alloc(InputIterator first, InputIterator last, ForwardIterator dest, \fn ForwardIterator uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator dest)
Alloc& alloc) \brief Equivalent of <code>std::uninitialized_copy</code> but with explicit specification of value type.
\brief Equivalent of <code>std::uninitialized_copy</code> with allocator.
*/ */
template<class InputIterator, class ForwardIterator, class Alloc> template<class ValueType, class InputIterator, class ForwardIterator>
inline ForwardIterator uninitialized_copy_with_alloc(InputIterator first, InputIterator last, ForwardIterator dest, inline ForwardIterator uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator dest) {
Alloc& alloc) { typedef ValueType value_type;
// We do not use allocator.construct and allocator.destroy
// because C++03 requires to take parameter by const reference but
// Boost.move requires nonconst reference
ForwardIterator next = dest; ForwardIterator next = dest;
BOOST_TRY { BOOST_TRY {
for (; first != last; ++first, ++dest) for (; first != last; ++first, ++dest)
alloc.construct(dest, *first); ::new (dest) value_type(*first);
} BOOST_CATCH(...) { } BOOST_CATCH(...) {
for (; next != dest; ++next) for (; next != dest; ++next)
alloc.destroy(next); next->~value_type();
BOOST_RETHROW BOOST_RETHROW
} }
BOOST_CATCH_END BOOST_CATCH_END
return dest; return dest;
} }
template<class ValueType, class InputIterator, class ForwardIterator>
ForwardIterator uninitialized_move_if_noexcept_impl(InputIterator first, InputIterator last, ForwardIterator dest,
true_type) {
for (; first != last; ++first, ++dest)
::new (dest) ValueType(boost::move(*first));
return dest;
}
template<class ValueType, class InputIterator, class ForwardIterator>
ForwardIterator uninitialized_move_if_noexcept_impl(InputIterator first, InputIterator last, ForwardIterator dest,
false_type) {
return uninitialized_copy<ValueType>(first, last, dest);
}
/*!
\fn ForwardIterator uninitialized_move_if_noexcept(InputIterator first, InputIterator last, ForwardIterator dest)
\brief Equivalent of <code>std::uninitialized_copy</code> but with explicit specification of value type and moves elements if they have noexcept move constructors.
*/
template<class ValueType, class InputIterator, class ForwardIterator>
ForwardIterator uninitialized_move_if_noexcept(InputIterator first, InputIterator last, ForwardIterator dest) {
typedef typename boost::is_nothrow_move_constructible<ValueType>::type tag_t;
return uninitialized_move_if_noexcept_impl<ValueType>(first, last, dest, tag_t());
}
/*! /*!
\fn void uninitialized_fill_n_with_alloc(ForwardIterator first, Diff n, const T& item, Alloc& alloc) \fn void uninitialized_fill_n_with_alloc(ForwardIterator first, Diff n, const T& item, Alloc& alloc)
\brief Equivalent of <code>std::uninitialized_fill_n</code> with allocator. \brief Equivalent of <code>std::uninitialized_fill_n</code> with allocator.
@ -467,4 +511,8 @@ inline void uninitialized_fill_n_with_alloc(ForwardIterator first, Diff n, const
} // namespace boost } // namespace boost
#if defined(_MSC_VER)
# pragma warning(pop)
#endif
#endif // #if !defined(BOOST_CIRCULAR_BUFFER_DETAILS_HPP) #endif // #if !defined(BOOST_CIRCULAR_BUFFER_DETAILS_HPP)

View File

@ -1,6 +1,8 @@
// Implementation of the circular buffer adaptor. // Implementation of the circular buffer adaptor.
// Copyright (c) 2003-2008 Jan Gaspar // Copyright (c) 2003-2008 Jan Gaspar
// Copyright (c) 2013 Paul A. Bristow // Doxygen comments changed for new version of documentation.
// Copyright (c) 2013 Antony Polukhin // Move semantics implementation.
// Use, modification, and distribution is subject to the Boost Software // Use, modification, and distribution is subject to the Boost Software
// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
@ -21,9 +23,8 @@ namespace boost {
/*! /*!
\class circular_buffer_space_optimized \class circular_buffer_space_optimized
\brief Space optimized circular buffer container adaptor. \brief Space optimized circular buffer container adaptor.
<code>T</code> must be a copyable class or must have an noexcept move constructor
For detailed documentation of the space_optimized_circular_buffer visit: and move assignment operator.
http://www.boost.org/libs/circular_buffer/doc/space_optimized.html
*/ */
template <class T, class Alloc> template <class T, class Alloc>
class circular_buffer_space_optimized : class circular_buffer_space_optimized :
@ -51,29 +52,53 @@ public:
typedef typename circular_buffer<T, Alloc>::array_range array_range; typedef typename circular_buffer<T, Alloc>::array_range array_range;
typedef typename circular_buffer<T, Alloc>::const_array_range const_array_range; typedef typename circular_buffer<T, Alloc>::const_array_range const_array_range;
typedef typename circular_buffer<T, Alloc>::param_value_type param_value_type; typedef typename circular_buffer<T, Alloc>::param_value_type param_value_type;
typedef typename circular_buffer<T, Alloc>::return_value_type return_value_type; typedef typename circular_buffer<T, Alloc>::rvalue_type rvalue_type;
//typedef typename circular_buffer<T, Alloc>::return_value_type return_value_type;
//! Capacity controller of the space optimized circular buffer. /* <pre> is not passed through to html or pdf. So <br> is used in code section below. Ugly :-(
/*! Ideally want a link to capacity_control, but this would require include details
<p><pre> and this would expose all the functions in details.
class capacity_control { There must be a better way of doing this.
size_type m_capacity; */
size_type m_min_capacity;
public: /*! Capacity controller of the space optimized circular buffer.
capacity_control(size_type capacity, size_type min_capacity = 0) : m_capacity(capacity), m_min_capacity(min_capacity) {};
size_type %capacity() const { return m_capacity; } \see capacity_control in details.hpp.
size_type min_capacity() const { return m_min_capacity; } <p>
operator size_type() const { return m_capacity; } <code>
};</pre></p> class capacity_control<br>
\pre <code>capacity >= min_capacity</code> {<br>
<p>The <code>capacity()</code> represents the capacity of the <code>circular_buffer_space_optimized</code> and size_type m_capacity; // Available capacity.<br>
the <code>min_capacity()</code> determines the minimal allocated size of its internal buffer.</p> size_type m_min_capacity; // Minimum capacity.<br>
public:<br>
capacity_control(size_type capacity, size_type min_capacity = 0)<br>
: m_capacity(capacity), m_min_capacity(min_capacity)<br>
{};<br>
size_type %capacity() const { return m_capacity; }<br>
size_type min_capacity() const { return m_min_capacity; }<br>
operator size_type() const { return m_capacity; }<br>
};<br>
</code>
</p>
<p>Always
<code>capacity >= min_capacity</code>.
</p>
<p>
The <code>capacity()</code> represents the capacity
of the <code>circular_buffer_space_optimized</code> and
the <code>min_capacity()</code> determines the minimal allocated size of its internal buffer.
</p>
<p>The converting constructor of the <code>capacity_control</code> allows implicit conversion from <p>The converting constructor of the <code>capacity_control</code> allows implicit conversion from
<code>size_type</code>-like types which ensures compatibility of creating an instance of the <code>size_type</code>-like types which ensures compatibility of creating an instance of the
<code>circular_buffer_space_optimized</code> with other STL containers. On the other hand the operator <code>circular_buffer_space_optimized</code> with other STL containers.
<code>%size_type()</code> provides implicit conversion to the <code>size_type</code> which allows to treat the
On the other hand the operator <code>%size_type()</code>
provides implicit conversion to the <code>size_type</code> which allows to treat the
capacity of the <code>circular_buffer_space_optimized</code> the same way as in the capacity of the <code>circular_buffer_space_optimized</code> the same way as in the
<code><a href="circular_buffer.html">circular_buffer</a></code>.</p> <code>circular_buffer</a></code>.
</p>
*/ */
typedef cb_details::capacity_control<size_type> capacity_type; typedef cb_details::capacity_control<size_type> capacity_type;
@ -98,7 +123,7 @@ public:
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) #if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
reference operator [] (size_type n) { return circular_buffer<T, Alloc>::operator[](n); } reference operator [] (size_type n) { return circular_buffer<T, Alloc>::operator[](n); }
return_value_type operator [] (size_type n) const { return circular_buffer<T, Alloc>::operator[](n); } const_reference operator [] (size_type n) const { return circular_buffer<T, Alloc>::operator[](n); }
#else #else
using circular_buffer<T, Alloc>::operator[]; using circular_buffer<T, Alloc>::operator[];
#endif #endif
@ -125,7 +150,7 @@ public:
Constant (in the size of the <code>circular_buffer_space_optimized</code>). Constant (in the size of the <code>circular_buffer_space_optimized</code>).
\sa <code>empty()</code> \sa <code>empty()</code>
*/ */
bool full() const { return m_capacity_ctrl == size(); } bool full() const BOOST_NOEXCEPT { return m_capacity_ctrl == size(); }
/*! \brief Get the maximum number of elements which can be inserted into the /*! \brief Get the maximum number of elements which can be inserted into the
<code>circular_buffer_space_optimized</code> without overwriting any of already stored elements. <code>circular_buffer_space_optimized</code> without overwriting any of already stored elements.
@ -139,7 +164,7 @@ public:
Constant (in the size of the <code>circular_buffer_space_optimized</code>). Constant (in the size of the <code>circular_buffer_space_optimized</code>).
\sa <code>capacity()</code>, <code>size()</code>, <code>max_size()</code> \sa <code>capacity()</code>, <code>size()</code>, <code>max_size()</code>
*/ */
size_type reserve() const { return m_capacity_ctrl - size(); } size_type reserve() const BOOST_NOEXCEPT { return m_capacity_ctrl - size(); }
//! Get the capacity of the <code>circular_buffer_space_optimized</code>. //! Get the capacity of the <code>circular_buffer_space_optimized</code>.
/*! /*!
@ -155,7 +180,7 @@ public:
\sa <code>reserve()</code>, <code>size()</code>, <code>max_size()</code>, \sa <code>reserve()</code>, <code>size()</code>, <code>max_size()</code>,
<code>set_capacity(const capacity_type&)</code> <code>set_capacity(const capacity_type&)</code>
*/ */
const capacity_type& capacity() const { return m_capacity_ctrl; } const capacity_type& capacity() const BOOST_NOEXCEPT { return m_capacity_ctrl; }
#if defined(BOOST_CB_TEST) #if defined(BOOST_CB_TEST)
@ -164,7 +189,7 @@ public:
\note This method is not intended to be used directly by the user. \note This method is not intended to be used directly by the user.
It is defined only for testing purposes. It is defined only for testing purposes.
*/ */
size_type internal_capacity() const { return circular_buffer<T, Alloc>::capacity(); } size_type internal_capacity() const BOOST_NOEXCEPT { return circular_buffer<T, Alloc>::capacity(); }
#endif // #if defined(BOOST_CB_TEST) #endif // #if defined(BOOST_CB_TEST)
@ -178,9 +203,9 @@ public:
than the new capacity then the amount of allocated memory in the internal buffer may be accommodated as than the new capacity then the amount of allocated memory in the internal buffer may be accommodated as
necessary but it will never drop below <code>capacity_ctrl.min_capacity()</code>. necessary but it will never drop below <code>capacity_ctrl.min_capacity()</code>.
\param capacity_ctrl The new capacity controller. \param capacity_ctrl The new capacity controller.
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is \throws "An allocation error" if memory is exhausted, (<code>std::bad_alloc</code> if the standard allocator is
used). used).
\throws Whatever <code>T::T(const T&)</code> throws. Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept.
\par Exception Safety \par Exception Safety
Strong. Strong.
\par Iterator Invalidation \par Iterator Invalidation
@ -222,7 +247,7 @@ public:
the requested size. (See the <i>Effect</i>.) the requested size. (See the <i>Effect</i>.)
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
used). used).
\throws Whatever <code>T::T(const T&)</code> throws. Whatever <code>T::T(const T&)</code> throws.
\par Exception Safety \par Exception Safety
Basic. Basic.
\par Iterator Invalidation \par Iterator Invalidation
@ -257,7 +282,7 @@ public:
\param capacity_ctrl The new capacity controller. \param capacity_ctrl The new capacity controller.
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
used). used).
\throws Whatever <code>T::T(const T&)</code> throws. Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept.
\par Exception Safety \par Exception Safety
Strong. Strong.
\par Iterator Invalidation \par Iterator Invalidation
@ -293,7 +318,7 @@ public:
the requested size. (See the <i>Effect</i>.) the requested size. (See the <i>Effect</i>.)
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
used). used).
\throws Whatever <code>T::T(const T&)</code> throws. Whatever <code>T::T(const T&)</code> throws.
\par Exception Safety \par Exception Safety
Basic. Basic.
\par Iterator Invalidation \par Iterator Invalidation
@ -324,7 +349,7 @@ public:
\warning Since Boost version 1.36 the behaviour of this constructor has changed. Now it creates a space \warning Since Boost version 1.36 the behaviour of this constructor has changed. Now it creates a space
optimized circular buffer with zero capacity. optimized circular buffer with zero capacity.
*/ */
explicit circular_buffer_space_optimized(const allocator_type& alloc = allocator_type()) explicit circular_buffer_space_optimized(const allocator_type& alloc = allocator_type()) BOOST_NOEXCEPT
: circular_buffer<T, Alloc>(0, alloc) : circular_buffer<T, Alloc>(0, alloc)
, m_capacity_ctrl(0) {} , m_capacity_ctrl(0) {}
@ -382,7 +407,7 @@ public:
\param alloc The allocator. \param alloc The allocator.
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
used). used).
\throws Whatever <code>T::T(const T&)</code> throws. Whatever <code>T::T(const T&)</code> throws.
\par Complexity \par Complexity
Linear (in the <code>n</code>). Linear (in the <code>n</code>).
*/ */
@ -424,7 +449,7 @@ public:
\param cb The <code>circular_buffer_space_optimized</code> to be copied. \param cb The <code>circular_buffer_space_optimized</code> to be copied.
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
used). used).
\throws Whatever <code>T::T(const T&)</code> throws. Whatever <code>T::T(const T&)</code> throws.
\par Complexity \par Complexity
Linear (in the size of <code>cb</code>). Linear (in the size of <code>cb</code>).
*/ */
@ -432,6 +457,23 @@ public:
: circular_buffer<T, Alloc>(cb.begin(), cb.end(), cb.get_allocator()) : circular_buffer<T, Alloc>(cb.begin(), cb.end(), cb.get_allocator())
, m_capacity_ctrl(cb.m_capacity_ctrl) {} , m_capacity_ctrl(cb.m_capacity_ctrl) {}
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
//! The move constructor.
/*! \brief Move constructs a <code>circular_buffer_space_optimized</code> from <code>cb</code>,
leaving <code>cb</code> empty.
\pre C++ compiler with rvalue references support.
\post <code>cb.empty()</code>
\param cb <code>circular_buffer</code> to 'steal' value from.
\throws Nothing.
\par Constant.
*/
circular_buffer_space_optimized(circular_buffer_space_optimized<T, Alloc>&& cb) BOOST_NOEXCEPT
: circular_buffer<T, Alloc>()
, m_capacity_ctrl(0) {
cb.swap(*this);
}
#endif // BOOST_NO_CXX11_RVALUE_REFERENCES
//! Create a full space optimized circular buffer filled with a copy of the range. //! Create a full space optimized circular buffer filled with a copy of the range.
/*! /*!
\pre Valid range <code>[first, last)</code>.<br> \pre Valid range <code>[first, last)</code>.<br>
@ -446,7 +488,8 @@ public:
\param alloc The allocator. \param alloc The allocator.
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
used). used).
\throws Whatever <code>T::T(const T&)</code> throws. Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept
and <code>InputIterator</code> is a move iterator.
\par Complexity \par Complexity
Linear (in the <code>std::distance(first, last)</code>). Linear (in the <code>std::distance(first, last)</code>).
*/ */
@ -477,7 +520,7 @@ public:
\param alloc The allocator. \param alloc The allocator.
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
used). used).
\throws Whatever <code>T::T(const T&)</code> throws. Whatever <code>T::T(const T&)</code> throws.
\par Complexity \par Complexity
Linear (in <code>std::distance(first, last)</code>; in Linear (in <code>std::distance(first, last)</code>; in
<code>min[capacity_ctrl.%capacity(), std::distance(first, last)]</code> if the <code>InputIterator</code> <code>min[capacity_ctrl.%capacity(), std::distance(first, last)]</code> if the <code>InputIterator</code>
@ -552,6 +595,24 @@ public:
return *this; return *this;
} }
#ifndef BOOST_NO_CXX11_RVALUE_REFERENCES
/*! \brief Move assigns content of <code>cb</code> to <code>*this</code>, leaving <code>cb</code> empty.
\pre C++ compiler with rvalue references support.
\post <code>cb.empty()</code>
\param cb <code>circular_buffer</code> to 'steal' value from.
\throws Nothing.
\par Complexity
Constant.
*/
circular_buffer_space_optimized<T, Alloc>& operator = (circular_buffer_space_optimized<T, Alloc>&& cb) BOOST_NOEXCEPT {
cb.swap(*this); // now `this` holds `cb`
circular_buffer<T, Alloc>(get_allocator()) // temprary that holds initial `cb` allocator
.swap(cb); // makes `cb` empty
return *this;
}
#endif // BOOST_NO_CXX11_RVALUE_REFERENCES
//! Assign <code>n</code> items into the space optimized circular buffer. //! Assign <code>n</code> items into the space optimized circular buffer.
/*! /*!
The content of the <code>circular_buffer_space_optimized</code> will be removed and replaced with The content of the <code>circular_buffer_space_optimized</code> will be removed and replaced with
@ -563,7 +624,7 @@ public:
\param item The element the <code>circular_buffer_space_optimized</code> will be filled with. \param item The element the <code>circular_buffer_space_optimized</code> will be filled with.
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
used). used).
\throws Whatever <code>T::T(const T&)</code> throws. Whatever <code>T::T(const T&)</code> throws.
\par Exception Safety \par Exception Safety
Basic. Basic.
\par Iterator Invalidation \par Iterator Invalidation
@ -596,7 +657,7 @@ public:
\param item The element the <code>circular_buffer_space_optimized</code> will be filled with. \param item The element the <code>circular_buffer_space_optimized</code> will be filled with.
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
used). used).
\throws Whatever <code>T::T(const T&)</code> throws. Whatever <code>T::T(const T&)</code> throws.
\par Exception Safety \par Exception Safety
Basic. Basic.
\par Iterator Invalidation \par Iterator Invalidation
@ -630,7 +691,8 @@ public:
\param last The end of the range to be copied. \param last The end of the range to be copied.
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
used). used).
\throws Whatever <code>T::T(const T&)</code> throws. Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept and
<code>InputIterator</code> is a move iterator.
\par Exception Safety \par Exception Safety
Basic. Basic.
\par Iterator Invalidation \par Iterator Invalidation
@ -670,7 +732,8 @@ public:
\param last The end of the range to be copied. \param last The end of the range to be copied.
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
used). used).
\throws Whatever <code>T::T(const T&)</code> throws. Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept and
<code>InputIterator</code> is a move iterator.
\par Exception Safety \par Exception Safety
Basic. Basic.
\par Iterator Invalidation \par Iterator Invalidation
@ -692,7 +755,7 @@ public:
circular_buffer<T, Alloc>::assign(capacity_ctrl, first, last); circular_buffer<T, Alloc>::assign(capacity_ctrl, first, last);
} }
//! Swap the contents of two space optimized circular buffers. //! Swap the contents of two space-optimized circular-buffers.
/*! /*!
\post <code>this</code> contains elements of <code>cb</code> and vice versa; the capacity and the amount of \post <code>this</code> contains elements of <code>cb</code> and vice versa; the capacity and the amount of
allocated memory in the internal buffer of <code>this</code> equal to the capacity and the amount of allocated memory in the internal buffer of <code>this</code> equal to the capacity and the amount of
@ -704,14 +767,18 @@ public:
\par Iterator Invalidation \par Iterator Invalidation
Invalidates all iterators of both <code>circular_buffer_space_optimized</code> containers. (On the other Invalidates all iterators of both <code>circular_buffer_space_optimized</code> containers. (On the other
hand the iterators still point to the same elements but within another container. If you want to rely on hand the iterators still point to the same elements but within another container. If you want to rely on
this feature you have to turn the <a href="circular_buffer.html#debug">Debug Support</a> off otherwise an this feature you have to turn the __debug_support off by defining macro BOOST_CB_DISABLE_DEBUG,
assertion will report an error if such invalidated iterator is used.) otherwise an assertion will report an error if such invalidated iterator is used.)
\par Complexity \par Complexity
Constant (in the size of the <code>circular_buffer_space_optimized</code>). Constant (in the size of the <code>circular_buffer_space_optimized</code>).
\sa <code>\link swap(circular_buffer<T, Alloc>&, circular_buffer<T, Alloc>&) \sa <code>swap(circular_buffer<T, Alloc>&, circular_buffer<T, Alloc>&)</code>,
swap(circular_buffer_space_optimized<T, Alloc>&, circular_buffer_space_optimized<T, Alloc>&)\endlink</code> <code>swap(circular_buffer_space_optimized<T, Alloc>&, circular_buffer_space_optimized<T, Alloc>&)</code>
*/ */
void swap(circular_buffer_space_optimized<T, Alloc>& cb) { // Note link does not work right. Asked on Doxygen forum for advice 23 May 2103.
void swap(circular_buffer_space_optimized<T, Alloc>& cb) BOOST_NOEXCEPT {
std::swap(m_capacity_ctrl, cb.m_capacity_ctrl); std::swap(m_capacity_ctrl, cb.m_capacity_ctrl);
circular_buffer<T, Alloc>::swap(cb); circular_buffer<T, Alloc>::swap(cb);
} }
@ -725,7 +792,7 @@ public:
\param item The element to be inserted. \param item The element to be inserted.
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
used). used).
\throws Whatever <code>T::T(const T&)</code> throws. Whatever <code>T::T(const T&)</code> throws.
\par Exception Safety \par Exception Safety
Basic. Basic.
\par Iterator Invalidation \par Iterator Invalidation
@ -736,11 +803,60 @@ public:
\sa <code>\link push_front() push_front(const_reference)\endlink</code>, <code>pop_back()</code>, \sa <code>\link push_front() push_front(const_reference)\endlink</code>, <code>pop_back()</code>,
<code>pop_front()</code> <code>pop_front()</code>
*/ */
void push_back(param_value_type item = value_type()) { void push_back(param_value_type item) {
check_low_capacity(); check_low_capacity();
circular_buffer<T, Alloc>::push_back(item); circular_buffer<T, Alloc>::push_back(item);
} }
//! Insert a new element at the end of the space optimized circular buffer.
/*!
\post if <code>capacity().%capacity() > 0</code> then <code>back() == item</code><br>
If the <code>circular_buffer_space_optimized</code> is full, the first element will be removed. If the
capacity is <code>0</code>, nothing will be inserted.<br><br>
The amount of allocated memory in the internal buffer may be predictively increased.
\param item The element to be inserted.
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
used).
\par Exception Safety
Basic.
\par Iterator Invalidation
Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
equal to <code>end()</code>).
\par Complexity
Linear (in the size of the <code>circular_buffer_space_optimized</code>).
\sa <code>\link push_front() push_front(const_reference)\endlink</code>, <code>pop_back()</code>,
<code>pop_front()</code>
*/
void push_back(rvalue_type item) {
check_low_capacity();
circular_buffer<T, Alloc>::push_back(boost::move(item));
}
//! Insert a new element at the end of the space optimized circular buffer.
/*!
\post if <code>capacity().%capacity() > 0</code> then <code>back() == item</code><br>
If the <code>circular_buffer_space_optimized</code> is full, the first element will be removed. If the
capacity is <code>0</code>, nothing will be inserted.<br><br>
The amount of allocated memory in the internal buffer may be predictively increased.
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
used).
Whatever <code>T::T()</code> throws.
Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept.
\par Exception Safety
Basic.
\par Iterator Invalidation
Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
equal to <code>end()</code>).
\par Complexity
Linear (in the size of the <code>circular_buffer_space_optimized</code>).
\sa <code>\link push_front() push_front(const_reference)\endlink</code>, <code>pop_back()</code>,
<code>pop_front()</code>
*/
void push_back() {
check_low_capacity();
circular_buffer<T, Alloc>::push_back();
}
//! Insert a new element at the beginning of the space optimized circular buffer. //! Insert a new element at the beginning of the space optimized circular buffer.
/*! /*!
\post if <code>capacity().%capacity() > 0</code> then <code>front() == item</code><br> \post if <code>capacity().%capacity() > 0</code> then <code>front() == item</code><br>
@ -750,7 +866,7 @@ public:
\param item The element to be inserted. \param item The element to be inserted.
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
used). used).
\throws Whatever <code>T::T(const T&)</code> throws. Whatever <code>T::T(const T&)</code> throws.
\par Exception Safety \par Exception Safety
Basic. Basic.
\par Iterator Invalidation \par Iterator Invalidation
@ -761,11 +877,61 @@ public:
\sa <code>\link push_back() push_back(const_reference)\endlink</code>, <code>pop_back()</code>, \sa <code>\link push_back() push_back(const_reference)\endlink</code>, <code>pop_back()</code>,
<code>pop_front()</code> <code>pop_front()</code>
*/ */
void push_front(param_value_type item = value_type()) { void push_front(param_value_type item) {
check_low_capacity(); check_low_capacity();
circular_buffer<T, Alloc>::push_front(item); circular_buffer<T, Alloc>::push_front(item);
} }
//! Insert a new element at the beginning of the space optimized circular buffer.
/*!
\post if <code>capacity().%capacity() > 0</code> then <code>front() == item</code><br>
If the <code>circular_buffer_space_optimized</code> is full, the last element will be removed. If the
capacity is <code>0</code>, nothing will be inserted.<br><br>
The amount of allocated memory in the internal buffer may be predictively increased.
\param item The element to be inserted.
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
used).
Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept.
\par Exception Safety
Basic.
\par Iterator Invalidation
Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
equal to <code>end()</code>).
\par Complexity
Linear (in the size of the <code>circular_buffer_space_optimized</code>).
\sa <code>\link push_back() push_back(const_reference)\endlink</code>, <code>pop_back()</code>,
<code>pop_front()</code>
*/
void push_front(rvalue_type item) {
check_low_capacity();
circular_buffer<T, Alloc>::push_front(boost::move(item));
}
//! Insert a new element at the beginning of the space optimized circular buffer.
/*!
\post if <code>capacity().%capacity() > 0</code> then <code>front() == item</code><br>
If the <code>circular_buffer_space_optimized</code> is full, the last element will be removed. If the
capacity is <code>0</code>, nothing will be inserted.<br><br>
The amount of allocated memory in the internal buffer may be predictively increased.
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
used).
Whatever <code>T::T()</code> throws.
Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept.
\par Exception Safety
Basic.
\par Iterator Invalidation
Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
equal to <code>end()</code>).
\par Complexity
Linear (in the size of the <code>circular_buffer_space_optimized</code>).
\sa <code>\link push_back() push_back(const_reference)\endlink</code>, <code>pop_back()</code>,
<code>pop_front()</code>
*/
void push_front() {
check_low_capacity();
circular_buffer<T, Alloc>::push_front();
}
//! Remove the last element from the space optimized circular buffer. //! Remove the last element from the space optimized circular buffer.
/*! /*!
\pre <code>!empty()</code> \pre <code>!empty()</code>
@ -826,8 +992,8 @@ public:
the <i>Effect</i>.) the <i>Effect</i>.)
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
used). used).
\throws Whatever <code>T::T(const T&)</code> throws. Whatever <code>T::T(const T&)</code> throws.
\throws Whatever <code>T::operator = (const T&)</code> throws. Whatever <code>T::operator = (const T&)</code> throws.
\par Exception Safety \par Exception Safety
Basic. Basic.
\par Iterator Invalidation \par Iterator Invalidation
@ -843,12 +1009,88 @@ public:
rinsert(iterator, size_type, value_type)\endlink</code>, rinsert(iterator, size_type, value_type)\endlink</code>,
<code>rinsert(iterator, InputIterator, InputIterator)</code> <code>rinsert(iterator, InputIterator, InputIterator)</code>
*/ */
iterator insert(iterator pos, param_value_type item = value_type()) { iterator insert(iterator pos, param_value_type item) {
size_type index = pos - begin(); size_type index = pos - begin();
check_low_capacity(); check_low_capacity();
return circular_buffer<T, Alloc>::insert(begin() + index, item); return circular_buffer<T, Alloc>::insert(begin() + index, item);
} }
//! Insert an element at the specified position.
/*!
\pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer_space_optimized</code> or its
end.
\post The <code>item</code> will be inserted at the position <code>pos</code>.<br>
If the <code>circular_buffer_space_optimized</code> is full, the first element will be overwritten. If
the <code>circular_buffer_space_optimized</code> is full and the <code>pos</code> points to
<code>begin()</code>, then the <code>item</code> will not be inserted. If the capacity is <code>0</code>,
nothing will be inserted.<br><br>
The amount of allocated memory in the internal buffer may be predictively increased.
\param pos An iterator specifying the position where the <code>item</code> will be inserted.
\param item The element to be inserted.
\return Iterator to the inserted element or <code>begin()</code> if the <code>item</code> is not inserted. (See
the <i>Effect</i>.)
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
used).
Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept.
\par Exception Safety
Basic.
\par Iterator Invalidation
Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
equal to <code>end()</code>).
\par Complexity
Linear (in the size of the <code>circular_buffer_space_optimized</code>).
\sa <code>\link insert(iterator, size_type, param_value_type)
insert(iterator, size_type, value_type)\endlink</code>,
<code>insert(iterator, InputIterator, InputIterator)</code>,
<code>\link rinsert(iterator, param_value_type) rinsert(iterator, value_type)\endlink</code>,
<code>\link rinsert(iterator, size_type, param_value_type)
rinsert(iterator, size_type, value_type)\endlink</code>,
<code>rinsert(iterator, InputIterator, InputIterator)</code>
*/
iterator insert(iterator pos, rvalue_type item) {
size_type index = pos - begin();
check_low_capacity();
return circular_buffer<T, Alloc>::insert(begin() + index, boost::move(item));
}
//! Insert an element at the specified position.
/*!
\pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer_space_optimized</code> or its
end.
\post The <code>item</code> will be inserted at the position <code>pos</code>.<br>
If the <code>circular_buffer_space_optimized</code> is full, the first element will be overwritten. If
the <code>circular_buffer_space_optimized</code> is full and the <code>pos</code> points to
<code>begin()</code>, then the <code>item</code> will not be inserted. If the capacity is <code>0</code>,
nothing will be inserted.<br><br>
The amount of allocated memory in the internal buffer may be predictively increased.
\param pos An iterator specifying the position where the <code>item</code> will be inserted.
\return Iterator to the inserted element or <code>begin()</code> if the <code>item</code> is not inserted. (See
the <i>Effect</i>.)
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
used).
Whatever <code>T::T()</code> throws.
Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept.
\par Exception Safety
Basic.
\par Iterator Invalidation
Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
equal to <code>end()</code>).
\par Complexity
Linear (in the size of the <code>circular_buffer_space_optimized</code>).
\sa <code>\link insert(iterator, size_type, param_value_type)
insert(iterator, size_type, value_type)\endlink</code>,
<code>insert(iterator, InputIterator, InputIterator)</code>,
<code>\link rinsert(iterator, param_value_type) rinsert(iterator, value_type)\endlink</code>,
<code>\link rinsert(iterator, size_type, param_value_type)
rinsert(iterator, size_type, value_type)\endlink</code>,
<code>rinsert(iterator, InputIterator, InputIterator)</code>
*/
iterator insert(iterator pos) {
size_type index = pos - begin();
check_low_capacity();
return circular_buffer<T, Alloc>::insert(begin() + index);
}
//! Insert <code>n</code> copies of the <code>item</code> at the specified position. //! Insert <code>n</code> copies of the <code>item</code> at the specified position.
/*! /*!
\pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer_space_optimized</code> or its \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer_space_optimized</code> or its
@ -863,8 +1105,8 @@ public:
\param item The element whose copies will be inserted. \param item The element whose copies will be inserted.
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
used). used).
\throws Whatever <code>T::T(const T&)</code> throws. Whatever <code>T::T(const T&)</code> throws.
\throws Whatever <code>T::operator = (const T&)</code> throws. Whatever <code>T::operator = (const T&)</code> throws.
\par Exception Safety \par Exception Safety
Basic. Basic.
\par Iterator Invalidation \par Iterator Invalidation
@ -876,7 +1118,7 @@ public:
Consider a <code>circular_buffer_space_optimized</code> with the capacity of 6 and the size of 4. Its Consider a <code>circular_buffer_space_optimized</code> with the capacity of 6 and the size of 4. Its
internal buffer may look like the one below.<br><br> internal buffer may look like the one below.<br><br>
<code>|1|2|3|4| | |</code><br> <code>|1|2|3|4| | |</code><br>
<code>p ---^</code><br><br>After inserting 5 elements at the position <code>p</code>:<br><br> <code>p ___^</code><br><br>After inserting 5 elements at the position <code>p</code>:<br><br>
<code>insert(p, (size_t)5, 0);</code><br><br>actually only 4 elements get inserted and elements <code>insert(p, (size_t)5, 0);</code><br><br>actually only 4 elements get inserted and elements
<code>1</code> and <code>2</code> are overwritten. This is due to the fact the insert operation preserves <code>1</code> and <code>2</code> are overwritten. This is due to the fact the insert operation preserves
the capacity. After insertion the internal buffer looks like this:<br><br><code>|0|0|0|0|3|4|</code><br> the capacity. After insertion the internal buffer looks like this:<br><br><code>|0|0|0|0|3|4|</code><br>
@ -911,8 +1153,7 @@ public:
\param last The end of the range to be inserted. \param last The end of the range to be inserted.
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
used). used).
\throws Whatever <code>T::T(const T&)</code> throws. Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept.
\throws Whatever <code>T::operator = (const T&)</code> throws.
\par Exception Safety \par Exception Safety
Basic. Basic.
\par Iterator Invalidation \par Iterator Invalidation
@ -927,7 +1168,7 @@ public:
Consider a <code>circular_buffer_space_optimized</code> with the capacity of 6 and the size of 4. Its Consider a <code>circular_buffer_space_optimized</code> with the capacity of 6 and the size of 4. Its
internal buffer may look like the one below.<br><br> internal buffer may look like the one below.<br><br>
<code>|1|2|3|4| | |</code><br> <code>|1|2|3|4| | |</code><br>
<code>p ---^</code><br><br>After inserting a range of elements at the position <code>p</code>:<br><br> <code>p ___^</code><br><br>After inserting a range of elements at the position <code>p</code>:<br><br>
<code>int array[] = { 5, 6, 7, 8, 9 };</code><br><code>insert(p, array, array + 5);</code><br><br> <code>int array[] = { 5, 6, 7, 8, 9 };</code><br><code>insert(p, array, array + 5);</code><br><br>
actually only elements <code>6</code>, <code>7</code>, <code>8</code> and <code>9</code> from the actually only elements <code>6</code>, <code>7</code>, <code>8</code> and <code>9</code> from the
specified range get inserted and elements <code>1</code> and <code>2</code> are overwritten. This is due specified range get inserted and elements <code>1</code> and <code>2</code> are overwritten. This is due
@ -962,8 +1203,8 @@ public:
the <i>Effect</i>.) the <i>Effect</i>.)
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
used). used).
\throws Whatever <code>T::T(const T&)</code> throws. Whatever <code>T::T(const T&)</code> throws.
\throws Whatever <code>T::operator = (const T&)</code> throws. Whatever <code>T::operator = (const T&)</code> throws.
\par Exception Safety \par Exception Safety
Basic. Basic.
\par Iterator Invalidation \par Iterator Invalidation
@ -979,12 +1220,88 @@ public:
insert(iterator, size_type, value_type)\endlink</code>, insert(iterator, size_type, value_type)\endlink</code>,
<code>insert(iterator, InputIterator, InputIterator)</code> <code>insert(iterator, InputIterator, InputIterator)</code>
*/ */
iterator rinsert(iterator pos, param_value_type item = value_type()) { iterator rinsert(iterator pos, param_value_type item) {
size_type index = pos - begin(); size_type index = pos - begin();
check_low_capacity(); check_low_capacity();
return circular_buffer<T, Alloc>::rinsert(begin() + index, item); return circular_buffer<T, Alloc>::rinsert(begin() + index, item);
} }
//! Insert an element before the specified position.
/*!
\pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer_space_optimized</code> or its
end.
\post The <code>item</code> will be inserted before the position <code>pos</code>.<br>
If the <code>circular_buffer_space_optimized</code> is full, the last element will be overwritten. If the
<code>circular_buffer_space_optimized</code> is full and the <code>pos</code> points to
<code>end()</code>, then the <code>item</code> will not be inserted. If the capacity is <code>0</code>,
nothing will be inserted.<br><br>
The amount of allocated memory in the internal buffer may be predictively increased.
\param pos An iterator specifying the position before which the <code>item</code> will be inserted.
\param item The element to be inserted.
\return Iterator to the inserted element or <code>end()</code> if the <code>item</code> is not inserted. (See
the <i>Effect</i>.)
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
used).
Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept.
\par Exception Safety
Basic.
\par Iterator Invalidation
Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
equal to <code>end()</code>).
\par Complexity
Linear (in the size of the <code>circular_buffer_space_optimized</code>).
\sa <code>\link rinsert(iterator, size_type, param_value_type)
rinsert(iterator, size_type, value_type)\endlink</code>,
<code>rinsert(iterator, InputIterator, InputIterator)</code>,
<code>\link insert(iterator, param_value_type) insert(iterator, value_type)\endlink</code>,
<code>\link insert(iterator, size_type, param_value_type)
insert(iterator, size_type, value_type)\endlink</code>,
<code>insert(iterator, InputIterator, InputIterator)</code>
*/
iterator rinsert(iterator pos, rvalue_type item) {
size_type index = pos - begin();
check_low_capacity();
return circular_buffer<T, Alloc>::rinsert(begin() + index, boost::move(item));
}
//! Insert an element before the specified position.
/*!
\pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer_space_optimized</code> or its
end.
\post The <code>item</code> will be inserted before the position <code>pos</code>.<br>
If the <code>circular_buffer_space_optimized</code> is full, the last element will be overwritten. If the
<code>circular_buffer_space_optimized</code> is full and the <code>pos</code> points to
<code>end()</code>, then the <code>item</code> will not be inserted. If the capacity is <code>0</code>,
nothing will be inserted.<br><br>
The amount of allocated memory in the internal buffer may be predictively increased.
\param pos An iterator specifying the position before which the <code>item</code> will be inserted.
\return Iterator to the inserted element or <code>end()</code> if the <code>item</code> is not inserted. (See
the <i>Effect</i>.)
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
used).
Whatever <code>T::T()</code> throws.
Whatever <code>T::T(const T&)</code> throws or nothing if <code>T::T(T&&)</code> is noexcept.
\par Exception Safety
Basic.
\par Iterator Invalidation
Invalidates all iterators pointing to the <code>circular_buffer_space_optimized</code> (except iterators
equal to <code>end()</code>).
\par Complexity
Linear (in the size of the <code>circular_buffer_space_optimized</code>).
\sa <code>\link rinsert(iterator, size_type, param_value_type)
rinsert(iterator, size_type, value_type)\endlink</code>,
<code>rinsert(iterator, InputIterator, InputIterator)</code>,
<code>\link insert(iterator, param_value_type) insert(iterator, value_type)\endlink</code>,
<code>\link insert(iterator, size_type, param_value_type)
insert(iterator, size_type, value_type)\endlink</code>,
<code>insert(iterator, InputIterator, InputIterator)</code>
*/
iterator rinsert(iterator pos) {
size_type index = pos - begin();
check_low_capacity();
return circular_buffer<T, Alloc>::rinsert(begin() + index);
}
//! Insert <code>n</code> copies of the <code>item</code> before the specified position. //! Insert <code>n</code> copies of the <code>item</code> before the specified position.
/*! /*!
\pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer_space_optimized</code> or its \pre <code>pos</code> is a valid iterator pointing to the <code>circular_buffer_space_optimized</code> or its
@ -999,8 +1316,8 @@ public:
\param item The element whose copies will be inserted. \param item The element whose copies will be inserted.
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
used). used).
\throws Whatever <code>T::T(const T&)</code> throws. Whatever <code>T::T(const T&)</code> throws.
\throws Whatever <code>T::operator = (const T&)</code> throws. Whatever <code>T::operator = (const T&)</code> throws.
\par Exception Safety \par Exception Safety
Basic. Basic.
\par Iterator Invalidation \par Iterator Invalidation
@ -1012,7 +1329,7 @@ public:
Consider a <code>circular_buffer_space_optimized</code> with the capacity of 6 and the size of 4. Its Consider a <code>circular_buffer_space_optimized</code> with the capacity of 6 and the size of 4. Its
internal buffer may look like the one below.<br><br> internal buffer may look like the one below.<br><br>
<code>|1|2|3|4| | |</code><br> <code>|1|2|3|4| | |</code><br>
<code>p ---^</code><br><br>After inserting 5 elements before the position <code>p</code>:<br><br> <code>p ___^</code><br><br>After inserting 5 elements before the position <code>p</code>:<br><br>
<code>rinsert(p, (size_t)5, 0);</code><br><br>actually only 4 elements get inserted and elements <code>rinsert(p, (size_t)5, 0);</code><br><br>actually only 4 elements get inserted and elements
<code>3</code> and <code>4</code> are overwritten. This is due to the fact the rinsert operation preserves <code>3</code> and <code>4</code> are overwritten. This is due to the fact the rinsert operation preserves
the capacity. After insertion the internal buffer looks like this:<br><br><code>|1|2|0|0|0|0|</code><br> the capacity. After insertion the internal buffer looks like this:<br><br><code>|1|2|0|0|0|0|</code><br>
@ -1048,8 +1365,8 @@ public:
\param last The end of the range to be inserted. \param last The end of the range to be inserted.
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
used). used).
\throws Whatever <code>T::T(const T&)</code> throws. Whatever <code>T::T(const T&)</code> throws.
\throws Whatever <code>T::operator = (const T&)</code> throws. Whatever <code>T::operator = (const T&)</code> throws.
\par Exception Safety \par Exception Safety
Basic. Basic.
\par Iterator Invalidation \par Iterator Invalidation
@ -1064,7 +1381,7 @@ public:
Consider a <code>circular_buffer_space_optimized</code> with the capacity of 6 and the size of 4. Its Consider a <code>circular_buffer_space_optimized</code> with the capacity of 6 and the size of 4. Its
internal buffer may look like the one below.<br><br> internal buffer may look like the one below.<br><br>
<code>|1|2|3|4| | |</code><br> <code>|1|2|3|4| | |</code><br>
<code>p ---^</code><br><br>After inserting a range of elements before the position <code>p</code>:<br><br> <code>p ___^</code><br><br>After inserting a range of elements before the position <code>p</code>:<br><br>
<code>int array[] = { 5, 6, 7, 8, 9 };</code><br><code>insert(p, array, array + 5);</code><br><br> <code>int array[] = { 5, 6, 7, 8, 9 };</code><br><code>insert(p, array, array + 5);</code><br><br>
actually only elements <code>5</code>, <code>6</code>, <code>7</code> and <code>8</code> from the actually only elements <code>5</code>, <code>6</code>, <code>7</code> and <code>8</code> from the
specified range get inserted and elements <code>3</code> and <code>4</code> are overwritten. This is due specified range get inserted and elements <code>3</code> and <code>4</code> are overwritten. This is due
@ -1094,7 +1411,8 @@ public:
element exists. element exists.
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
used). used).
\throws Whatever <code>T::operator = (const T&)</code> throws. Whatever <code>T::operator = (const T&)</code> throws or
nothing if <code>T::operator = (T&&)</code> is noexcept.
\par Exception Safety \par Exception Safety
Basic. Basic.
\par Iterator Invalidation \par Iterator Invalidation
@ -1124,7 +1442,8 @@ public:
element exists. element exists.
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
used). used).
\throws Whatever <code>T::operator = (const T&)</code> throws. Whatever <code>T::operator = (const T&)</code> throws or
nothing if <code>T::operator = (T&&)</code> is noexcept.
\par Exception Safety \par Exception Safety
Basic. Basic.
\par Iterator Invalidation \par Iterator Invalidation
@ -1153,7 +1472,8 @@ public:
such element exists. such element exists.
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
used). used).
\throws Whatever <code>T::operator = (const T&)</code> throws. Whatever <code>T::operator = (const T&)</code> throws or
nothing if <code>T::operator = (T&&)</code> is noexcept.
\par Exception Safety \par Exception Safety
Basic. Basic.
\par Iterator Invalidation \par Iterator Invalidation
@ -1162,7 +1482,7 @@ public:
\par Complexity \par Complexity
Linear (in the size of the <code>circular_buffer_space_optimized</code>). Linear (in the size of the <code>circular_buffer_space_optimized</code>).
\note Basically there is no difference between <code>erase(iterator)</code> and this method. It is implemented \note Basically there is no difference between <code>erase(iterator)</code> and this method. It is implemented
only for consistency with the base <code><a href="circular_buffer.html">circular_buffer</a></code>. only for consistency with the base <code>circular_buffer</code>.
\sa <code>erase(iterator)</code>, <code>erase(iterator, iterator)</code>, \sa <code>erase(iterator)</code>, <code>erase(iterator, iterator)</code>,
<code>rerase(iterator, iterator)</code>, <code>clear()</code> <code>rerase(iterator, iterator)</code>, <code>clear()</code>
*/ */
@ -1185,7 +1505,8 @@ public:
such element exists. such element exists.
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is \throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
used). used).
\throws Whatever <code>T::operator = (const T&)</code> throws. Whatever <code>T::operator = (const T&)</code> throws or
nothing if <code>T::operator = (T&&)</code> is noexcept.
\par Exception Safety \par Exception Safety
Basic. Basic.
\par Iterator Invalidation \par Iterator Invalidation
@ -1195,7 +1516,7 @@ public:
Linear (in the size of the <code>circular_buffer_space_optimized</code>). Linear (in the size of the <code>circular_buffer_space_optimized</code>).
\note Basically there is no difference between <code>erase(iterator, iterator)</code> and this method. It is \note Basically there is no difference between <code>erase(iterator, iterator)</code> and this method. It is
implemented only for consistency with the base implemented only for consistency with the base
<code><a href="circular_buffer.html">circular_buffer</a></code>. <code><circular_buffer</code>.
\sa <code>erase(iterator)</code>, <code>erase(iterator, iterator)</code>, <code>rerase(iterator)</code>, \sa <code>erase(iterator)</code>, <code>erase(iterator, iterator)</code>, <code>rerase(iterator)</code>,
<code>clear()</code> <code>clear()</code>
*/ */
@ -1414,7 +1735,7 @@ inline bool operator >= (const circular_buffer_space_optimized<T, Alloc>& lhs,
//! Swap the contents of two space optimized circular buffers. //! Swap the contents of two space optimized circular buffers.
template <class T, class Alloc> template <class T, class Alloc>
inline void swap(circular_buffer_space_optimized<T, Alloc>& lhs, inline void swap(circular_buffer_space_optimized<T, Alloc>& lhs,
circular_buffer_space_optimized<T, Alloc>& rhs) { circular_buffer_space_optimized<T, Alloc>& rhs) BOOST_NOEXCEPT {
lhs.swap(rhs); lhs.swap(rhs);
} }

View File

@ -56,15 +56,8 @@
// get config suffix code: // get config suffix code:
#include <boost/config/suffix.hpp> #include <boost/config/suffix.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
#endif // BOOST_CONFIG_HPP #endif // BOOST_CONFIG_HPP

View File

@ -151,11 +151,16 @@ BOOST_LIB_VERSION: The Boost version, in the form x_y, for Boost version x.y.
// vc10: // vc10:
# define BOOST_LIB_TOOLSET "vc100" # define BOOST_LIB_TOOLSET "vc100"
# elif defined(BOOST_MSVC) # elif defined(BOOST_MSVC) && (BOOST_MSVC < 1800)
// vc11: // vc11:
# define BOOST_LIB_TOOLSET "vc110" # define BOOST_LIB_TOOLSET "vc110"
# elif defined(BOOST_MSVC)
// vc12:
# define BOOST_LIB_TOOLSET "vc120"
# elif defined(__BORLANDC__) # elif defined(__BORLANDC__)
// CBuilder 6: // CBuilder 6:
@ -421,3 +426,4 @@ BOOST_LIB_VERSION: The Boost version, in the form x_y, for Boost version x.y.
# undef BOOST_DYN_LINK # undef BOOST_DYN_LINK
#endif #endif

View File

@ -191,6 +191,9 @@
#define BOOST_NO_CXX11_NOEXCEPT #define BOOST_NO_CXX11_NOEXCEPT
#define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX #define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX
#define BOOST_NO_CXX11_USER_DEFINED_LITERALS #define BOOST_NO_CXX11_USER_DEFINED_LITERALS
#define BOOST_NO_CXX11_ALIGNAS
#define BOOST_NO_CXX11_TRAILING_RESULT_TYPES
#define BOOST_NO_CXX11_INLINE_NAMESPACES
#if __BORLANDC__ >= 0x590 #if __BORLANDC__ >= 0x590
# define BOOST_HAS_TR1_HASH # define BOOST_HAS_TR1_HASH
@ -282,7 +285,3 @@
#define BOOST_NO_COMPLETE_VALUE_INITIALIZATION #define BOOST_NO_COMPLETE_VALUE_INITIALIZATION
#define BOOST_COMPILER "Borland C++ version " BOOST_STRINGIZE(__BORLANDC__) #define BOOST_COMPILER "Borland C++ version " BOOST_STRINGIZE(__BORLANDC__)

View File

@ -8,6 +8,8 @@
// Clang compiler setup. // Clang compiler setup.
#define BOOST_HAS_PRAGMA_ONCE
#if !__has_feature(cxx_exceptions) && !defined(BOOST_NO_EXCEPTIONS) #if !__has_feature(cxx_exceptions) && !defined(BOOST_NO_EXCEPTIONS)
# define BOOST_NO_EXCEPTIONS # define BOOST_NO_EXCEPTIONS
#endif #endif
@ -26,6 +28,14 @@
#define BOOST_HAS_NRVO #define BOOST_HAS_NRVO
// Branch prediction hints
#if defined(__has_builtin)
#if __has_builtin(__builtin_expect)
#define BOOST_LIKELY(x) __builtin_expect(x, 1)
#define BOOST_UNLIKELY(x) __builtin_expect(x, 0)
#endif
#endif
// Clang supports "long long" in all compilation modes. // Clang supports "long long" in all compilation modes.
#define BOOST_HAS_LONG_LONG #define BOOST_HAS_LONG_LONG
@ -146,6 +156,18 @@
# define BOOST_NO_CXX11_USER_DEFINED_LITERALS # define BOOST_NO_CXX11_USER_DEFINED_LITERALS
#endif #endif
#if !(__has_feature(cxx_alignas) || __has_extension(cxx_alignas))
# define BOOST_NO_CXX11_ALIGNAS
#endif
#if !__has_feature(cxx_trailing_return)
# define BOOST_NO_CXX11_TRAILING_RESULT_TYPES
#endif
#if !__has_feature(cxx_inline_namespaces)
# define BOOST_NO_CXX11_INLINE_NAMESPACES
#endif
// Clang always supports variadic macros // Clang always supports variadic macros
// Clang always supports extern templates // Clang always supports extern templates

View File

@ -72,6 +72,12 @@
# endif # endif
#endif #endif
// Reportedly, #pragma once is supported since C++ Builder 2010
#if (__CODEGEARC__ >= 0x620)
# define BOOST_HAS_PRAGMA_ONCE
#endif
// //
// C++0x macros: // C++0x macros:
// //
@ -111,6 +117,9 @@
#define BOOST_NO_CXX11_VARIADIC_TEMPLATES #define BOOST_NO_CXX11_VARIADIC_TEMPLATES
#define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX #define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX
#define BOOST_NO_CXX11_USER_DEFINED_LITERALS #define BOOST_NO_CXX11_USER_DEFINED_LITERALS
#define BOOST_NO_CXX11_ALIGNAS
#define BOOST_NO_CXX11_TRAILING_RESULT_TYPES
#define BOOST_NO_CXX11_INLINE_NAMESPACES
// //
// TR1 macros: // TR1 macros:

View File

@ -54,6 +54,11 @@
# define BOOST_NO_LONG_LONG # define BOOST_NO_LONG_LONG
# endif # endif
// Not sure what version was the first to support #pragma once, but
// different EDG-based compilers (e.g. Intel) supported it for ages.
// Add a proper version check if it causes problems.
#define BOOST_HAS_PRAGMA_ONCE
// //
// C++0x features // C++0x features
// //
@ -96,6 +101,9 @@
#define BOOST_NO_CXX11_VARIADIC_TEMPLATES #define BOOST_NO_CXX11_VARIADIC_TEMPLATES
#define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX #define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX
#define BOOST_NO_CXX11_USER_DEFINED_LITERALS #define BOOST_NO_CXX11_USER_DEFINED_LITERALS
#define BOOST_NO_CXX11_ALIGNAS
#define BOOST_NO_CXX11_TRAILING_RESULT_TYPES
#define BOOST_NO_CXX11_INLINE_NAMESPACES
#ifdef c_plusplus #ifdef c_plusplus
// EDG has "long long" in non-strict mode // EDG has "long long" in non-strict mode

View File

@ -55,6 +55,7 @@
#define BOOST_NO_COMPLETE_VALUE_INITIALIZATION #define BOOST_NO_COMPLETE_VALUE_INITIALIZATION
#define BOOST_NO_CXX11_CHAR32_T #define BOOST_NO_CXX11_CHAR32_T
#define BOOST_NO_CXX11_CHAR16_T #define BOOST_NO_CXX11_CHAR16_T
#define BOOST_NO_CXX11_ALIGNAS
//#define BOOST_BCB_PARTIAL_SPECIALIZATION_BUG //#define BOOST_BCB_PARTIAL_SPECIALIZATION_BUG
#define BOOST_MATH_DISABLE_STD_FPCLASSIFY #define BOOST_MATH_DISABLE_STD_FPCLASSIFY
//#define BOOST_HAS_FPCLASSIFY //#define BOOST_HAS_FPCLASSIFY

View File

@ -11,15 +11,7 @@
#define BOOST_HAS_LONG_LONG #define BOOST_HAS_LONG_LONG
#define BOOST_HAS_PRAGMA_ONCE #define BOOST_HAS_PRAGMA_ONCE
#if (__DMC__ <= 0x833) #if !defined(BOOST_STRICT_CONFIG)
#define BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL
#define BOOST_NO_TEMPLATE_TEMPLATES
#define BOOST_NEEDS_TOKEN_PASTING_OP_FOR_TOKENS_JUXTAPOSING
#define BOOST_NO_ARRAY_TYPE_SPECIALIZATIONS
#define BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS
#endif
#if (__DMC__ <= 0x840) || !defined(BOOST_STRICT_CONFIG)
#define BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS
#define BOOST_NO_MEMBER_TEMPLATE_FRIENDS #define BOOST_NO_MEMBER_TEMPLATE_FRIENDS
#define BOOST_NO_OPERATORS_IN_NAMESPACE #define BOOST_NO_OPERATORS_IN_NAMESPACE
#define BOOST_NO_UNREACHABLE_RETURN_DETECTION #define BOOST_NO_UNREACHABLE_RETURN_DETECTION
@ -30,11 +22,9 @@
// //
// has macros: // has macros:
#if (__DMC__ >= 0x840)
#define BOOST_HAS_DIRENT_H #define BOOST_HAS_DIRENT_H
#define BOOST_HAS_STDINT_H #define BOOST_HAS_STDINT_H
#define BOOST_HAS_WINTHREADS #define BOOST_HAS_WINTHREADS
#endif
#if (__DMC__ >= 0x847) #if (__DMC__ >= 0x847)
#define BOOST_HAS_EXPM1 #define BOOST_HAS_EXPM1
@ -87,12 +77,11 @@
#define BOOST_NO_CXX11_VARIADIC_TEMPLATES #define BOOST_NO_CXX11_VARIADIC_TEMPLATES
#define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX #define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX
#define BOOST_NO_CXX11_USER_DEFINED_LITERALS #define BOOST_NO_CXX11_USER_DEFINED_LITERALS
#define BOOST_NO_CXX11_ALIGNAS
#define BOOST_NO_CXX11_TRAILING_RESULT_TYPES
#define BOOST_NO_CXX11_INLINE_NAMESPACES
#if (__DMC__ < 0x812) #if (__DMC__ <= 0x840)
#define BOOST_NO_CXX11_VARIADIC_MACROS
#endif
#if __DMC__ < 0x800
#error "Compiler not supported or configured - please reconfigure" #error "Compiler not supported or configured - please reconfigure"
#endif #endif
// //

View File

@ -20,51 +20,12 @@
#define BOOST_GCC (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) #define BOOST_GCC (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
#endif #endif
#if __GNUC__ < 3 #if __GNUC__ == 3
# if __GNUC_MINOR__ == 91
// egcs 1.1 won't parse shared_ptr.hpp without this:
# define BOOST_NO_AUTO_PTR
# endif
# if __GNUC_MINOR__ < 95
//
// Prior to gcc 2.95 member templates only partly
// work - define BOOST_MSVC6_MEMBER_TEMPLATES
// instead since inline member templates mostly work.
//
# define BOOST_NO_MEMBER_TEMPLATES
# if __GNUC_MINOR__ >= 9
# define BOOST_MSVC6_MEMBER_TEMPLATES
# endif
# endif
# if __GNUC_MINOR__ < 96
# define BOOST_NO_SFINAE
# endif
# if __GNUC_MINOR__ <= 97
# define BOOST_NO_MEMBER_TEMPLATE_FRIENDS
# define BOOST_NO_OPERATORS_IN_NAMESPACE
# endif
# define BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE
# define BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL
# define BOOST_NO_IS_ABSTRACT
# define BOOST_NO_CXX11_EXTERN_TEMPLATE
// Variadic macros do not exist for gcc versions before 3.0
# define BOOST_NO_CXX11_VARIADIC_MACROS
#elif __GNUC__ == 3
# if defined (__PATHSCALE__) # if defined (__PATHSCALE__)
# define BOOST_NO_TWO_PHASE_NAME_LOOKUP # define BOOST_NO_TWO_PHASE_NAME_LOOKUP
# define BOOST_NO_IS_ABSTRACT # define BOOST_NO_IS_ABSTRACT
# endif # endif
//
// gcc-3.x problems:
//
// Bug specific to gcc 3.1 and 3.2:
//
# if ((__GNUC_MINOR__ == 1) || (__GNUC_MINOR__ == 2))
# define BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS
# endif
# if __GNUC_MINOR__ < 4 # if __GNUC_MINOR__ < 4
# define BOOST_NO_IS_ABSTRACT # define BOOST_NO_IS_ABSTRACT
# endif # endif
@ -80,6 +41,11 @@
# endif # endif
#endif #endif
// GCC prior to 3.4 had #pragma once too but it didn't work well with filesystem links
#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
#define BOOST_HAS_PRAGMA_ONCE
#endif
#if __GNUC__ < 4 || ( __GNUC__ == 4 && __GNUC_MINOR__ < 4 ) #if __GNUC__ < 4 || ( __GNUC__ == 4 && __GNUC_MINOR__ < 4 )
// Previous versions of GCC did not completely implement value-initialization: // Previous versions of GCC did not completely implement value-initialization:
// GCC Bug 30111, "Value-initialization of POD base class doesn't initialize // GCC Bug 30111, "Value-initialization of POD base class doesn't initialize
@ -114,9 +80,11 @@
// //
// gcc implements the named return value optimization since version 3.1 // gcc implements the named return value optimization since version 3.1
// //
#if __GNUC__ > 3 || ( __GNUC__ == 3 && __GNUC_MINOR__ >= 1 )
#define BOOST_HAS_NRVO #define BOOST_HAS_NRVO
#endif
// Branch prediction hints
#define BOOST_LIKELY(x) __builtin_expect(x, 1)
#define BOOST_UNLIKELY(x) __builtin_expect(x, 0)
// //
// Dynamic shared object (DSO) and dynamic-link library (DLL) support // Dynamic shared object (DSO) and dynamic-link library (DLL) support
@ -127,13 +95,13 @@
// _WIN32 or one of its variant spellings. Note that Cygwin is a POSIX environment, // _WIN32 or one of its variant spellings. Note that Cygwin is a POSIX environment,
// so does not define _WIN32 or its variants. // so does not define _WIN32 or its variants.
# define BOOST_HAS_DECLSPEC # define BOOST_HAS_DECLSPEC
# define BOOST_SYMBOL_EXPORT __attribute__((dllexport)) # define BOOST_SYMBOL_EXPORT __attribute__((__dllexport__))
# define BOOST_SYMBOL_IMPORT __attribute__((dllimport)) # define BOOST_SYMBOL_IMPORT __attribute__((__dllimport__))
# else # else
# define BOOST_SYMBOL_EXPORT __attribute__((visibility("default"))) # define BOOST_SYMBOL_EXPORT __attribute__((__visibility__("default")))
# define BOOST_SYMBOL_IMPORT # define BOOST_SYMBOL_IMPORT
# endif # endif
# define BOOST_SYMBOL_VISIBLE __attribute__((visibility("default"))) # define BOOST_SYMBOL_VISIBLE __attribute__((__visibility__("default")))
#else #else
// config/platform/win32.hpp will define BOOST_SYMBOL_EXPORT, etc., unless already defined // config/platform/win32.hpp will define BOOST_SYMBOL_EXPORT, etc., unless already defined
# define BOOST_SYMBOL_EXPORT # define BOOST_SYMBOL_EXPORT
@ -202,12 +170,19 @@
# define BOOST_NO_CXX11_HDR_INITIALIZER_LIST # define BOOST_NO_CXX11_HDR_INITIALIZER_LIST
# define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS # define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS
# define BOOST_NO_CXX11_DELETED_FUNCTIONS # define BOOST_NO_CXX11_DELETED_FUNCTIONS
# define BOOST_NO_CXX11_TRAILING_RESULT_TYPES
# define BOOST_NO_CXX11_INLINE_NAMESPACES
#endif #endif
#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 5) #if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 5)
# define BOOST_NO_SFINAE_EXPR # define BOOST_NO_SFINAE_EXPR
#endif #endif
// GCC 4.5 forbids declaration of defaulted functions in private or protected sections
#if !defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) && (__GNUC__ == 4 && __GNUC_MINOR__ <= 5)
# define BOOST_NO_CXX11_NON_PUBLIC_DEFAULTED_FUNCTIONS
#endif
// C++0x features in 4.5.0 and later // C++0x features in 4.5.0 and later
// //
#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 5) || !defined(__GXX_EXPERIMENTAL_CXX0X__) #if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 5) || !defined(__GXX_EXPERIMENTAL_CXX0X__)
@ -243,6 +218,12 @@
# define BOOST_NO_CXX11_USER_DEFINED_LITERALS # define BOOST_NO_CXX11_USER_DEFINED_LITERALS
#endif #endif
// C++0x features in 4.8.n and later
//
#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 8) || !defined(__GXX_EXPERIMENTAL_CXX0X__)
# define BOOST_NO_CXX11_ALIGNAS
#endif
// C++0x features in 4.8.1 and later // C++0x features in 4.8.1 and later
// //
#if (__GNUC__*10000 + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__ < 40801) || !defined(__GXX_EXPERIMENTAL_CXX0X__) #if (__GNUC__*10000 + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__ < 40801) || !defined(__GXX_EXPERIMENTAL_CXX0X__)
@ -261,8 +242,8 @@
#endif #endif
// versions check: // versions check:
// we don't know gcc prior to version 2.90: // we don't know gcc prior to version 3.30:
#if (__GNUC__ == 2) && (__GNUC_MINOR__ < 90) #if (__GNUC__ < 3) || (__GNUC__ == 3 && (__GNUC_MINOR__ < 3))
# error "Compiler not configured - please reconfigure" # error "Compiler not configured - please reconfigure"
#endif #endif
// //

View File

@ -55,6 +55,9 @@
# define BOOST_NO_CXX11_NOEXCEPT # define BOOST_NO_CXX11_NOEXCEPT
# define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX # define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX
# define BOOST_NO_CXX11_USER_DEFINED_LITERALS # define BOOST_NO_CXX11_USER_DEFINED_LITERALS
# define BOOST_NO_CXX11_ALIGNAS
# define BOOST_NO_CXX11_TRAILING_RESULT_TYPES
# define BOOST_NO_CXX11_INLINE_NAMESPACES
#define BOOST_COMPILER "GCC-XML C++ version " __GCCXML__ #define BOOST_COMPILER "GCC-XML C++ version " __GCCXML__

View File

@ -119,6 +119,9 @@
#define BOOST_NO_CXX11_UNICODE_LITERALS #define BOOST_NO_CXX11_UNICODE_LITERALS
#define BOOST_NO_CXX11_VARIADIC_TEMPLATES #define BOOST_NO_CXX11_VARIADIC_TEMPLATES
#define BOOST_NO_CXX11_USER_DEFINED_LITERALS #define BOOST_NO_CXX11_USER_DEFINED_LITERALS
#define BOOST_NO_CXX11_ALIGNAS
#define BOOST_NO_CXX11_TRAILING_RESULT_TYPES
#define BOOST_NO_CXX11_INLINE_NAMESPACES
/* /*
See https://forums13.itrc.hp.com/service/forums/questionanswer.do?threadId=1443331 and See https://forums13.itrc.hp.com/service/forums/questionanswer.do?threadId=1443331 and

View File

@ -27,7 +27,7 @@
#endif #endif
// Flags determined by comparing output of 'icpc -dM -E' with and without '-std=c++0x' // Flags determined by comparing output of 'icpc -dM -E' with and without '-std=c++0x'
#if (!(defined(_WIN32) || defined(_WIN64)) && defined(__STDC_HOSTED__) && (__STDC_HOSTED__ && (BOOST_INTEL_CXX_VERSION <= 1200))) || defined(__GXX_EXPERIMENTAL_CPP0X__) #if (!(defined(_WIN32) || defined(_WIN64)) && defined(__STDC_HOSTED__) && (__STDC_HOSTED__ && (BOOST_INTEL_CXX_VERSION <= 1200))) || defined(__GXX_EXPERIMENTAL_CPP0X__) || defined(__GXX_EXPERIMENTAL_CXX0X__)
# define BOOST_INTEL_STDCXX0X # define BOOST_INTEL_STDCXX0X
#endif #endif
#if defined(_MSC_VER) && (_MSC_VER >= 1600) #if defined(_MSC_VER) && (_MSC_VER >= 1600)
@ -47,11 +47,6 @@
# define BOOST_INTEL_LINUX BOOST_INTEL # define BOOST_INTEL_LINUX BOOST_INTEL
#endif #endif
#if (BOOST_INTEL_CXX_VERSION <= 500) && defined(_MSC_VER)
# define BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS
# define BOOST_NO_TEMPLATE_TEMPLATES
#endif
#if (BOOST_INTEL_CXX_VERSION <= 600) #if (BOOST_INTEL_CXX_VERSION <= 600)
# if defined(_MSC_VER) && (_MSC_VER <= 1300) // added check for <= VC 7 (Peter Dimov) # if defined(_MSC_VER) && (_MSC_VER <= 1300) // added check for <= VC 7 (Peter Dimov)
@ -111,7 +106,7 @@
# define BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL # define BOOST_FUNCTION_SCOPE_USING_DECLARATION_BREAKS_ADL
# endif # endif
#endif #endif
#if (defined(__GNUC__) && (__GNUC__ < 4)) || defined(_WIN32) || (BOOST_INTEL_CXX_VERSION <= 1200) #if (defined(__GNUC__) && (__GNUC__ < 4)) || (defined(_WIN32) && (BOOST_INTEL_CXX_VERSION <= 1200)) || (BOOST_INTEL_CXX_VERSION <= 1200)
// GCC or VC emulation: // GCC or VC emulation:
#define BOOST_NO_TWO_PHASE_NAME_LOOKUP #define BOOST_NO_TWO_PHASE_NAME_LOOKUP
#endif #endif
@ -154,10 +149,18 @@ template<> struct assert_intrinsic_wchar_t<unsigned short> {};
# define BOOST_HAS_NRVO # define BOOST_HAS_NRVO
#endif #endif
// Branch prediction hints
// I'm not sure 8.0 was the first version to support these builtins,
// update the condition if the version is not accurate. (Andrey Semashev)
#if defined(__GNUC__) && BOOST_INTEL_CXX_VERSION >= 800
#define BOOST_LIKELY(x) __builtin_expect(x, 1)
#define BOOST_UNLIKELY(x) __builtin_expect(x, 0)
#endif
// //
// versions check: // versions check:
// we don't support Intel prior to version 5.0: // we don't support Intel prior to version 6.0:
#if BOOST_INTEL_CXX_VERSION < 500 #if BOOST_INTEL_CXX_VERSION < 600
# error "Compiler not supported or configured - please reconfigure" # error "Compiler not supported or configured - please reconfigure"
#endif #endif
@ -221,6 +224,7 @@ template<> struct assert_intrinsic_wchar_t<unsigned short> {};
# undef BOOST_NO_CXX11_DECLTYPE # undef BOOST_NO_CXX11_DECLTYPE
# undef BOOST_NO_CXX11_AUTO_DECLARATIONS # undef BOOST_NO_CXX11_AUTO_DECLARATIONS
# undef BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS # undef BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS
# undef BOOST_NO_CXX11_TRAILING_RESULT_TYPES
#endif #endif
// icl Version 12.1.0.233 Build 20110811 and possibly some other builds // icl Version 12.1.0.233 Build 20110811 and possibly some other builds
@ -237,6 +241,42 @@ template<> struct assert_intrinsic_wchar_t<unsigned short> {};
// continues to list scoped enum support as "Partial" // continues to list scoped enum support as "Partial"
//# undef BOOST_NO_CXX11_SCOPED_ENUMS //# undef BOOST_NO_CXX11_SCOPED_ENUMS
#endif #endif
#if defined(BOOST_INTEL_STDCXX0X) && (BOOST_INTEL_CXX_VERSION >= 1310) && !defined(_MSC_VER)
# undef BOOST_NO_CXX11_INLINE_NAMESPACES
# undef BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS
// This one generates internal compiler errors in multiprecision, disabled for now:
//# undef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
// This one generates errors when used with conditional exception specifications, for example in multiprecision:
//# undef BOOST_NO_CXX11_NOEXCEPT
# undef BOOST_NO_CXX11_RANGE_BASED_FOR
# undef BOOST_NO_CXX11_SCOPED_ENUMS
# undef BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX
#endif
#if (BOOST_INTEL_CXX_VERSION >= 1310)
# undef BOOST_NO_SFINAE_EXPR
#endif
#if defined(BOOST_INTEL_STDCXX0X) && (BOOST_INTEL_CXX_VERSION >= 1400) && !defined(_MSC_VER)
# undef BOOST_NO_CXX11_UNICODE_LITERALS
# undef BOOST_NO_CXX11_RAW_LITERALS
// This one generates errors when used with conditional exception specifications, for example in multiprecision:
//# undef BOOST_NO_CXX11_NOEXCEPT
// This breaks multiprecision:
//# undef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
# undef BOOST_NO_CXX11_HDR_THREAD
# undef BOOST_NO_CXX11_CHAR32_T
# undef BOOST_NO_CXX11_CHAR16_T
#endif
#if defined(BOOST_INTEL_STDCXX0X) && (BOOST_INTEL_CXX_VERSION <= 1310)
# define BOOST_NO_CXX11_HDR_FUTURE
# define BOOST_NO_CXX11_HDR_INITIALIZER_LIST
#endif
#if defined(BOOST_INTEL_STDCXX0X) && (BOOST_INTEL_CXX_VERSION == 1400)
// A regression in Intel's compiler means that <tuple> seems to be broken in this release as well as <future> :
# define BOOST_NO_CXX11_HDR_FUTURE
# define BOOST_NO_CXX11_HDR_TUPLE
#endif
#if defined(_MSC_VER) && (_MSC_VER <= 1700) #if defined(_MSC_VER) && (_MSC_VER <= 1700)
// //
@ -247,6 +287,9 @@ template<> struct assert_intrinsic_wchar_t<unsigned short> {};
# define BOOST_NO_CXX11_DELETED_FUNCTIONS # define BOOST_NO_CXX11_DELETED_FUNCTIONS
# define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS # define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS
# define BOOST_NO_CXX11_TEMPLATE_ALIASES # define BOOST_NO_CXX11_TEMPLATE_ALIASES
# if(BOOST_INTEL_CXX_VERSION < 1310)
# define BOOST_NO_CXX11_TRAILING_RESULT_TYPES
# endif
#endif #endif
#if (BOOST_INTEL_CXX_VERSION < 1200) #if (BOOST_INTEL_CXX_VERSION < 1200)
@ -256,9 +299,17 @@ template<> struct assert_intrinsic_wchar_t<unsigned short> {};
# define BOOST_NO_FENV_H # define BOOST_NO_FENV_H
#endif #endif
#if defined(_MSC_VER) && (_MSC_VER >= 1600)
# define BOOST_HAS_STDINT_H
#endif
#if defined(__LP64__) && defined(__GNUC__) && (BOOST_INTEL_CXX_VERSION >= 1310)
# define BOOST_HAS_INT128
#endif
// //
// last known and checked version: // last known and checked version:
#if (BOOST_INTEL_CXX_VERSION > 1200) #if (BOOST_INTEL_CXX_VERSION > 1310)
# if defined(BOOST_ASSERT_CONFIG) # if defined(BOOST_ASSERT_CONFIG)
# error "Unknown compiler version - please run the configure tests and report the results" # error "Unknown compiler version - please run the configure tests and report the results"
# elif defined(_MSC_VER) # elif defined(_MSC_VER)

View File

@ -120,6 +120,9 @@
#define BOOST_NO_CXX11_VARIADIC_MACROS #define BOOST_NO_CXX11_VARIADIC_MACROS
#define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX #define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX
#define BOOST_NO_CXX11_USER_DEFINED_LITERALS #define BOOST_NO_CXX11_USER_DEFINED_LITERALS
#define BOOST_NO_CXX11_ALIGNAS
#define BOOST_NO_CXX11_TRAILING_RESULT_TYPES
#define BOOST_NO_CXX11_INLINE_NAMESPACES
#define BOOST_COMPILER "Metrowerks CodeWarrior C++ version " BOOST_STRINGIZE(BOOST_COMPILER_VERSION) #define BOOST_COMPILER "Metrowerks CodeWarrior C++ version " BOOST_STRINGIZE(BOOST_COMPILER_VERSION)

View File

@ -69,6 +69,9 @@
#define BOOST_NO_CXX11_VARIADIC_MACROS #define BOOST_NO_CXX11_VARIADIC_MACROS
#define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX #define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX
#define BOOST_NO_CXX11_USER_DEFINED_LITERALS #define BOOST_NO_CXX11_USER_DEFINED_LITERALS
#define BOOST_NO_CXX11_ALIGNAS
#define BOOST_NO_CXX11_TRAILING_RESULT_TYPES
#define BOOST_NO_CXX11_INLINE_NAMESPACES
// //
// versions check: // versions check:

View File

@ -14,15 +14,3 @@
// NVIDIA Specific support // NVIDIA Specific support
// BOOST_GPU_ENABLED : Flag a function or a method as being enabled on the host and device // BOOST_GPU_ENABLED : Flag a function or a method as being enabled on the host and device
#define BOOST_GPU_ENABLED __host__ __device__ #define BOOST_GPU_ENABLED __host__ __device__
// Boost support macro for NVCC
// NVCC Basically behaves like some flavor of MSVC6 + some specific quirks
#ifdef __GNUC__
#include <boost/config/compiler/gcc.hpp>
#elif defined(_MSC_VER)
#include <boost/config/compiler/visualc.hpp>
#endif

View File

@ -77,5 +77,7 @@
# define BOOST_NO_CXX11_HDR_CODECVT # define BOOST_NO_CXX11_HDR_CODECVT
# define BOOST_NO_CXX11_HDR_CHRONO # define BOOST_NO_CXX11_HDR_CHRONO
# define BOOST_NO_CXX11_USER_DEFINED_LITERALS # define BOOST_NO_CXX11_USER_DEFINED_LITERALS
# define BOOST_NO_CXX11_ALIGNAS
# define BOOST_NO_CXX11_TRAILING_RESULT_TYPES
# define BOOST_NO_CXX11_INLINE_NAMESPACES
#endif #endif

View File

@ -41,6 +41,9 @@
#define BOOST_HAS_THREADS #define BOOST_HAS_THREADS
#define BOOST_HAS_NRVO #define BOOST_HAS_NRVO
#define BOOST_HAS_LONG_LONG #define BOOST_HAS_LONG_LONG
#if defined(linux) || defined(__linux) || defined(__linux__)
# define BOOST_HAS_STDINT_H
#endif
// options --enable-test wants undefined // options --enable-test wants undefined
#undef BOOST_NO_STDC_NAMESPACE #undef BOOST_NO_STDC_NAMESPACE
@ -112,6 +115,9 @@
#define BOOST_NO_CXX11_HDR_CHRONO #define BOOST_NO_CXX11_HDR_CHRONO
#define BOOST_NO_CXX11_HDR_ARRAY #define BOOST_NO_CXX11_HDR_ARRAY
#define BOOST_NO_CXX11_USER_DEFINED_LITERALS #define BOOST_NO_CXX11_USER_DEFINED_LITERALS
#define BOOST_NO_CXX11_ALIGNAS
#define BOOST_NO_CXX11_TRAILING_RESULT_TYPES
#define BOOST_NO_CXX11_INLINE_NAMESPACES
// //
// version check: // version check:

View File

@ -128,6 +128,9 @@
#define BOOST_NO_CXX11_VARIADIC_MACROS #define BOOST_NO_CXX11_VARIADIC_MACROS
#define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX #define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX
#define BOOST_NO_CXX11_USER_DEFINED_LITERALS #define BOOST_NO_CXX11_USER_DEFINED_LITERALS
#define BOOST_NO_CXX11_ALIGNAS
#define BOOST_NO_CXX11_TRAILING_RESULT_TYPES
#define BOOST_NO_CXX11_INLINE_NAMESPACES
// //
// Version // Version

View File

@ -126,6 +126,6 @@
#if ! __C99_MACRO_WITH_VA_ARGS #if ! __C99_MACRO_WITH_VA_ARGS
# define BOOST_NO_CXX11_VARIADIC_MACROS # define BOOST_NO_CXX11_VARIADIC_MACROS
#endif #endif
#define BOOST_NO_CXX11_ALIGNAS
#define BOOST_NO_CXX11_TRAILING_RESULT_TYPES
#define BOOST_NO_CXX11_INLINE_NAMESPACES

View File

@ -34,64 +34,17 @@
// Attempt to suppress VC6 warnings about the length of decorated names (obsolete): // Attempt to suppress VC6 warnings about the length of decorated names (obsolete):
#pragma warning( disable : 4503 ) // warning: decorated name length exceeded #pragma warning( disable : 4503 ) // warning: decorated name length exceeded
#define BOOST_HAS_PRAGMA_ONCE
// //
// versions check: // versions check:
// we don't support Visual C++ prior to version 6: // we don't support Visual C++ prior to version 7.1:
#if _MSC_VER < 1200 #if _MSC_VER < 1310
# error "Compiler not supported or configured - please reconfigure" # error "Compiler not supported or configured - please reconfigure"
#endif #endif
#if _MSC_VER < 1300 // 1200 == VC++ 6.0, 1200-1202 == eVC++4 #if _MSC_FULL_VER < 180020827
# pragma warning( disable : 4786 ) // ident trunc to '255' chars in debug info
# define BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS
# define BOOST_NO_VOID_RETURNS
# define BOOST_NO_EXCEPTION_STD_NAMESPACE
# if _MSC_VER == 1202
# define BOOST_NO_STD_TYPEINFO
# endif
#endif
/// Visual Studio has no fenv.h
# define BOOST_NO_FENV_H # define BOOST_NO_FENV_H
#if (_MSC_VER < 1310) // 130X == VC++ 7.0
# if !defined(_MSC_EXTENSIONS) && !defined(BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS) // VC7 bug with /Za
# define BOOST_NO_DEPENDENT_TYPES_IN_TEMPLATE_VALUE_PARAMETERS
# endif
# define BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS
# define BOOST_NO_INCLASS_MEMBER_INITIALIZATION
# define BOOST_NO_PRIVATE_IN_AGGREGATE
# define BOOST_NO_ARGUMENT_DEPENDENT_LOOKUP
# define BOOST_NO_INTEGRAL_INT64_T
# define BOOST_NO_DEDUCED_TYPENAME
# define BOOST_NO_USING_DECLARATION_OVERLOADS_FROM_TYPENAME_BASE
// VC++ 6/7 has member templates but they have numerous problems including
// cases of silent failure, so for safety we define:
# define BOOST_NO_MEMBER_TEMPLATES
// For VC++ experts wishing to attempt workarounds, we define:
# define BOOST_MSVC6_MEMBER_TEMPLATES
# define BOOST_NO_MEMBER_TEMPLATE_FRIENDS
# define BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION
# define BOOST_NO_CV_VOID_SPECIALIZATIONS
# define BOOST_NO_FUNCTION_TEMPLATE_ORDERING
# define BOOST_NO_USING_TEMPLATE
# define BOOST_NO_SWPRINTF
# define BOOST_NO_TEMPLATE_TEMPLATES
# define BOOST_NO_SFINAE
# define BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS
# define BOOST_NO_IS_ABSTRACT
# define BOOST_NO_FUNCTION_TYPE_SPECIALIZATIONS
// TODO: what version is meant here? Have there really been any fixes in cl 12.01 (as e.g. shipped with eVC4)?
# if (_MSC_VER >= 1300)
# define BOOST_NO_MEMBER_FUNCTION_SPECIALIZATIONS
# endif
#endif #endif
#if _MSC_VER < 1400 #if _MSC_VER < 1400
@ -157,10 +110,8 @@
// //
// __int64 support: // __int64 support:
// //
#if (_MSC_VER >= 1200)
#define BOOST_HAS_MS_INT64 #define BOOST_HAS_MS_INT64
#endif #if defined(_MSC_EXTENSIONS) || (_MSC_VER >= 1400)
#if (_MSC_VER >= 1310) && (defined(_MSC_EXTENSIONS) || (_MSC_VER >= 1400))
# define BOOST_HAS_LONG_LONG # define BOOST_HAS_LONG_LONG
#else #else
# define BOOST_NO_LONG_LONG # define BOOST_NO_LONG_LONG
@ -210,21 +161,23 @@
# define BOOST_HAS_STDINT_H # define BOOST_HAS_STDINT_H
#endif #endif
// C++ features supported by VC++ 11 (aka 2012) // C++11 features supported by VC++ 11 (aka 2012)
// //
#if _MSC_VER < 1700 #if _MSC_VER < 1700
# define BOOST_NO_CXX11_RANGE_BASED_FOR # define BOOST_NO_CXX11_RANGE_BASED_FOR
# define BOOST_NO_CXX11_SCOPED_ENUMS # define BOOST_NO_CXX11_SCOPED_ENUMS
#endif // _MSC_VER < 1700 #endif // _MSC_VER < 1700
// C++11 features supported by VC++ 11 (aka 2012) November 2012 CTP // C++11 features supported by VC++ 12 (aka 2013).
// Because the CTP is unsupported, unrelease, and only alpha quality,
// it is only supported if BOOST_MSVC_ENABLE_2012_NOV_CTP is defined.
// //
#if _MSC_FULL_VER < 170051025 || !defined(BOOST_MSVC_ENABLE_2012_NOV_CTP) #if _MSC_FULL_VER < 180020827
# define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS
# define BOOST_NO_CXX11_DELETED_FUNCTIONS
# define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS # define BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS
# define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS # define BOOST_NO_CXX11_FUNCTION_TEMPLATE_DEFAULT_ARGS
# define BOOST_NO_CXX11_RAW_LITERALS # define BOOST_NO_CXX11_RAW_LITERALS
# define BOOST_NO_CXX11_TEMPLATE_ALIASES
# define BOOST_NO_CXX11_TRAILING_RESULT_TYPES
# define BOOST_NO_CXX11_VARIADIC_TEMPLATES # define BOOST_NO_CXX11_VARIADIC_TEMPLATES
# define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX # define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX
#endif #endif
@ -234,14 +187,13 @@
#define BOOST_NO_CXX11_CHAR32_T #define BOOST_NO_CXX11_CHAR32_T
#define BOOST_NO_CXX11_CONSTEXPR #define BOOST_NO_CXX11_CONSTEXPR
#define BOOST_NO_CXX11_DECLTYPE_N3276 #define BOOST_NO_CXX11_DECLTYPE_N3276
#define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS
#define BOOST_NO_CXX11_DELETED_FUNCTIONS
#define BOOST_NO_CXX11_NOEXCEPT #define BOOST_NO_CXX11_NOEXCEPT
#define BOOST_NO_CXX11_TEMPLATE_ALIASES
#define BOOST_NO_CXX11_UNICODE_LITERALS #define BOOST_NO_CXX11_UNICODE_LITERALS
#define BOOST_NO_SFINAE_EXPR #define BOOST_NO_SFINAE_EXPR
#define BOOST_NO_TWO_PHASE_NAME_LOOKUP #define BOOST_NO_TWO_PHASE_NAME_LOOKUP
#define BOOST_NO_CXX11_USER_DEFINED_LITERALS #define BOOST_NO_CXX11_USER_DEFINED_LITERALS
#define BOOST_NO_CXX11_ALIGNAS
#define BOOST_NO_CXX11_INLINE_NAMESPACES
// //
// prefix and suffix headers: // prefix and suffix headers:
@ -261,11 +213,7 @@
// were shipped with freely downloadable SDKs, others as crosscompilers in eVC. // were shipped with freely downloadable SDKs, others as crosscompilers in eVC.
// IOW, you can't use these 'versions' in any sensible way. Sorry. // IOW, you can't use these 'versions' in any sensible way. Sorry.
# if defined(UNDER_CE) # if defined(UNDER_CE)
# if _MSC_VER < 1200 # if _MSC_VER < 1400
// Note: these are so far off, they are not really supported
# elif _MSC_VER < 1300 // eVC++ 4 comes with 1200-1202
# define BOOST_COMPILER_VERSION evc4.0
# elif _MSC_VER < 1400
// Note: I'm not aware of any CE compiler with version 13xx // Note: I'm not aware of any CE compiler with version 13xx
# if defined(BOOST_ASSERT_CONFIG) # if defined(BOOST_ASSERT_CONFIG)
# error "Unknown EVC++ compiler version - please run the configure tests and report the results" # error "Unknown EVC++ compiler version - please run the configure tests and report the results"
@ -280,6 +228,8 @@
# define BOOST_COMPILER_VERSION evc10 # define BOOST_COMPILER_VERSION evc10
# elif _MSC_VER < 1800 # elif _MSC_VER < 1800
# define BOOST_COMPILER_VERSION evc11 # define BOOST_COMPILER_VERSION evc11
# elif _MSC_VER < 1900
# define BOOST_COMPILER_VERSION evc12
# else # else
# if defined(BOOST_ASSERT_CONFIG) # if defined(BOOST_ASSERT_CONFIG)
# error "Unknown EVC++ compiler version - please run the configure tests and report the results" # error "Unknown EVC++ compiler version - please run the configure tests and report the results"
@ -288,8 +238,8 @@
# endif # endif
# endif # endif
# else # else
# if _MSC_VER < 1200 # if _MSC_VER < 1310
// Note: these are so far off, they are not really supported // Note: Versions up to 7.0 aren't supported.
# define BOOST_COMPILER_VERSION 5.0 # define BOOST_COMPILER_VERSION 5.0
# elif _MSC_VER < 1300 # elif _MSC_VER < 1300
# define BOOST_COMPILER_VERSION 6.0 # define BOOST_COMPILER_VERSION 6.0
@ -305,6 +255,8 @@
# define BOOST_COMPILER_VERSION 10.0 # define BOOST_COMPILER_VERSION 10.0
# elif _MSC_VER < 1800 # elif _MSC_VER < 1800
# define BOOST_COMPILER_VERSION 11.0 # define BOOST_COMPILER_VERSION 11.0
# elif _MSC_VER < 1900
# define BOOST_COMPILER_VERSION 12.0
# else # else
# define BOOST_COMPILER_VERSION _MSC_VER # define BOOST_COMPILER_VERSION _MSC_VER
# endif # endif
@ -314,8 +266,8 @@
#endif #endif
// //
// last known and checked version is 1700 (VC11, aka 2011): // last known and checked version is 18.00.20827.3 (VC12 RC, aka 2013 RC):
#if (_MSC_VER > 1700) #if (_MSC_VER > 1800 && _MSC_FULL_VER > 180020827)
# if defined(BOOST_ASSERT_CONFIG) # if defined(BOOST_ASSERT_CONFIG)
# error "Unknown compiler version - please run the configure tests and report the results" # error "Unknown compiler version - please run the configure tests and report the results"
# else # else

View File

@ -13,6 +13,12 @@
// locate which compiler we are using and define // locate which compiler we are using and define
// BOOST_COMPILER_CONFIG as needed: // BOOST_COMPILER_CONFIG as needed:
#if defined __CUDACC__
// NVIDIA CUDA C++ compiler for GPU
# include "boost/config/compiler/nvcc.hpp"
#endif
#if defined(__GCCXML__) #if defined(__GCCXML__)
// GCC-XML emulates other compilers, it has to appear first here! // GCC-XML emulates other compilers, it has to appear first here!
# define BOOST_COMPILER_CONFIG "boost/config/compiler/gcc_xml.hpp" # define BOOST_COMPILER_CONFIG "boost/config/compiler/gcc_xml.hpp"
@ -21,10 +27,6 @@
// EDG based Cray compiler: // EDG based Cray compiler:
# define BOOST_COMPILER_CONFIG "boost/config/compiler/cray.hpp" # define BOOST_COMPILER_CONFIG "boost/config/compiler/cray.hpp"
#elif defined __CUDACC__
// NVIDIA CUDA C++ compiler for GPU
# define BOOST_COMPILER_CONFIG "boost/config/compiler/nvcc.hpp"
#elif defined __COMO__ #elif defined __COMO__
// Comeau C++ // Comeau C++
# define BOOST_COMPILER_CONFIG "boost/config/compiler/comeau.hpp" # define BOOST_COMPILER_CONFIG "boost/config/compiler/comeau.hpp"

View File

@ -110,7 +110,8 @@
# define BOOST_NO_CXX11_SMART_PTR # define BOOST_NO_CXX11_SMART_PTR
#endif #endif
#if (!defined(_HAS_TR1_IMPORTS) || (_HAS_TR1_IMPORTS+0 == 0)) && !defined(BOOST_NO_CXX11_HDR_TUPLE) #if ((!defined(_HAS_TR1_IMPORTS) || (_HAS_TR1_IMPORTS+0 == 0)) && !defined(BOOST_NO_CXX11_HDR_TUPLE)) \
&& (!defined(_CPPLIB_VER) || _CPPLIB_VER < 610)
# define BOOST_NO_CXX11_HDR_TUPLE # define BOOST_NO_CXX11_HDR_TUPLE
#endif #endif
@ -128,10 +129,11 @@
# define BOOST_NO_CXX11_ATOMIC_SMART_PTR # define BOOST_NO_CXX11_ATOMIC_SMART_PTR
#endif #endif
// C++0x headers implemented in 610 (as shipped by Microsoft)
// //
// C++0x headers not yet (fully) implemented: #if !defined(_CPPLIB_VER) || _CPPLIB_VER < 610
//
# define BOOST_NO_CXX11_HDR_INITIALIZER_LIST # define BOOST_NO_CXX11_HDR_INITIALIZER_LIST
#endif
#ifdef _CPPLIB_VER #ifdef _CPPLIB_VER
# define BOOST_DINKUMWARE_STDLIB _CPPLIB_VER # define BOOST_DINKUMWARE_STDLIB _CPPLIB_VER

View File

@ -503,69 +503,8 @@ namespace boost{
#endif #endif
// BOOST_[APPEND_]EXPLICIT_TEMPLATE_[NON_]TYPE macros --------------------------// // BOOST_[APPEND_]EXPLICIT_TEMPLATE_[NON_]TYPE macros --------------------------//
//
// Some compilers have problems with function templates whose template
// parameters don't appear in the function parameter list (basically
// they just link one instantiation of the template in the final
// executable). These macros provide a uniform way to cope with the
// problem with no effects on the calling syntax.
// Example: // These macros are obsolete. Port away and remove.
//
// #include <iostream>
// #include <ostream>
// #include <typeinfo>
//
// template <int n>
// void f() { std::cout << n << ' '; }
//
// template <typename T>
// void g() { std::cout << typeid(T).name() << ' '; }
//
// int main() {
// f<1>();
// f<2>();
//
// g<int>();
// g<double>();
// }
//
// With VC++ 6.0 the output is:
//
// 2 2 double double
//
// To fix it, write
//
// template <int n>
// void f(BOOST_EXPLICIT_TEMPLATE_NON_TYPE(int, n)) { ... }
//
// template <typename T>
// void g(BOOST_EXPLICIT_TEMPLATE_TYPE(T)) { ... }
//
#if defined(BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS) && defined(__cplusplus)
# include "boost/type.hpp"
# include "boost/non_type.hpp"
# define BOOST_EXPLICIT_TEMPLATE_TYPE(t) boost::type<t>* = 0
# define BOOST_EXPLICIT_TEMPLATE_TYPE_SPEC(t) boost::type<t>*
# define BOOST_EXPLICIT_TEMPLATE_NON_TYPE(t, v) boost::non_type<t, v>* = 0
# define BOOST_EXPLICIT_TEMPLATE_NON_TYPE_SPEC(t, v) boost::non_type<t, v>*
# define BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE(t) \
, BOOST_EXPLICIT_TEMPLATE_TYPE(t)
# define BOOST_APPEND_EXPLICIT_TEMPLATE_TYPE_SPEC(t) \
, BOOST_EXPLICIT_TEMPLATE_TYPE_SPEC(t)
# define BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(t, v) \
, BOOST_EXPLICIT_TEMPLATE_NON_TYPE(t, v)
# define BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE_SPEC(t, v) \
, BOOST_EXPLICIT_TEMPLATE_NON_TYPE_SPEC(t, v)
#else
// no workaround needed: expand to nothing
# define BOOST_EXPLICIT_TEMPLATE_TYPE(t) # define BOOST_EXPLICIT_TEMPLATE_TYPE(t)
# define BOOST_EXPLICIT_TEMPLATE_TYPE_SPEC(t) # define BOOST_EXPLICIT_TEMPLATE_TYPE_SPEC(t)
@ -577,9 +516,6 @@ namespace boost{
# define BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(t, v) # define BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE(t, v)
# define BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE_SPEC(t, v) # define BOOST_APPEND_EXPLICIT_TEMPLATE_NON_TYPE_SPEC(t, v)
#endif // defined BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS
// When BOOST_NO_STD_TYPEINFO is defined, we can just import // When BOOST_NO_STD_TYPEINFO is defined, we can just import
// the global definition into std namespace: // the global definition into std namespace:
#if defined(BOOST_NO_STD_TYPEINFO) && defined(__cplusplus) #if defined(BOOST_NO_STD_TYPEINFO) && defined(__cplusplus)
@ -648,6 +584,78 @@ namespace std{ using ::type_info; }
# endif # endif
#endif #endif
// BOOST_NOINLINE ---------------------------------------------//
// Macro to use in place of 'inline' to prevent a function to be inlined
#if !defined(BOOST_NOINLINE)
# if defined(_MSC_VER)
# define BOOST_NOINLINE __declspec(noinline)
# elif defined(__GNUC__) && __GNUC__ > 3
// Clang also defines __GNUC__ (as 4)
# define BOOST_NOINLINE __attribute__ ((__noinline__))
# else
# define BOOST_NOINLINE
# endif
#endif
// Branch prediction hints
// These macros are intended to wrap conditional expressions that yield true or false
//
// if (BOOST_LIKELY(var == 10))
// {
// // the most probable code here
// }
//
#if !defined(BOOST_LIKELY)
# define BOOST_LIKELY(x) x
#endif
#if !defined(BOOST_UNLIKELY)
# define BOOST_UNLIKELY(x) x
#endif
// Type and data alignment specification
//
#if !defined(BOOST_NO_CXX11_ALIGNAS)
# define BOOST_ALIGNMENT(x) alignas(x)
#elif defined(_MSC_VER)
# define BOOST_ALIGNMENT(x) __declspec(align(x))
#elif defined(__GNUC__)
# define BOOST_ALIGNMENT(x) __attribute__ ((__aligned__(x)))
#else
# define BOOST_NO_ALIGNMENT
# define BOOST_ALIGNMENT(x)
#endif
// Defaulted and deleted function declaration helpers
// These macros are intended to be inside a class definition.
// BOOST_DEFAULTED_FUNCTION accepts the function declaration and its
// body, which will be used if the compiler doesn't support defaulted functions.
// BOOST_DELETED_FUNCTION only accepts the function declaration. It
// will expand to a private function declaration, if the compiler doesn't support
// deleted functions. Because of this it is recommended to use BOOST_DELETED_FUNCTION
// in the end of the class definition.
//
// class my_class
// {
// public:
// // Default-constructible
// BOOST_DEFAULTED_FUNCTION(my_class(), {})
// // Copying prohibited
// BOOST_DELETED_FUNCTION(my_class(my_class const&))
// BOOST_DELETED_FUNCTION(my_class& operator= (my_class const&))
// };
//
#if !(defined(BOOST_NO_CXX11_DEFAULTED_FUNCTIONS) || defined(BOOST_NO_CXX11_NON_PUBLIC_DEFAULTED_FUNCTIONS))
# define BOOST_DEFAULTED_FUNCTION(fun, body) fun = default;
#else
# define BOOST_DEFAULTED_FUNCTION(fun, body) fun body
#endif
#if !defined(BOOST_NO_CXX11_DELETED_FUNCTIONS)
# define BOOST_DELETED_FUNCTION(fun) fun = delete;
#else
# define BOOST_DELETED_FUNCTION(fun) private: fun;
#endif
// //
// Set BOOST_NO_DECLTYPE_N3276 when BOOST_NO_DECLTYPE is defined // Set BOOST_NO_DECLTYPE_N3276 when BOOST_NO_DECLTYPE is defined
// //

View File

@ -17,12 +17,13 @@
#ifndef BOOST_CONTAINER_ALLOCATOR_ALLOCATOR_TRAITS_HPP #ifndef BOOST_CONTAINER_ALLOCATOR_ALLOCATOR_TRAITS_HPP
#define BOOST_CONTAINER_ALLOCATOR_ALLOCATOR_TRAITS_HPP #define BOOST_CONTAINER_ALLOCATOR_ALLOCATOR_TRAITS_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200) #if defined(_MSC_VER)
# pragma once # pragma once
#endif #endif
#include <boost/container/detail/config_begin.hpp> #include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp> #include <boost/container/detail/workaround.hpp>
#include <boost/container/container_fwd.hpp>
#include <boost/intrusive/pointer_traits.hpp> #include <boost/intrusive/pointer_traits.hpp>
#include <boost/intrusive/detail/memory_util.hpp> #include <boost/intrusive/detail/memory_util.hpp>
#include <boost/container/detail/memory_util.hpp> #include <boost/container/detail/memory_util.hpp>
@ -387,6 +388,10 @@ struct allocator_traits
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
#include BOOST_PP_LOCAL_ITERATE() #include BOOST_PP_LOCAL_ITERATE()
#endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES) #endif // #if !defined(BOOST_NO_CXX11_VARIADIC_TEMPLATES)
template<class T>
static void priv_construct_dispatch2(boost::false_type, Alloc &, T *p, ::boost::container::default_init_t)
{ ::new((void*)p) T; }
#endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED) #endif //#if defined(BOOST_CONTAINER_DOXYGEN_INVOKED)
///@endcond ///@endcond

View File

@ -11,7 +11,7 @@
#ifndef BOOST_CONTAINER_CONTAINER_FWD_HPP #ifndef BOOST_CONTAINER_CONTAINER_FWD_HPP
#define BOOST_CONTAINER_CONTAINER_FWD_HPP #define BOOST_CONTAINER_CONTAINER_FWD_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200) #if defined(_MSC_VER)
# pragma once # pragma once
#endif #endif
@ -135,20 +135,28 @@ class basic_string;
struct ordered_range_t struct ordered_range_t
{}; {};
//! Value used to tag that the input range is
//! guaranteed to be ordered
static const ordered_range_t ordered_range = ordered_range_t();
//! Type used to tag that the input range is //! Type used to tag that the input range is
//! guaranteed to be ordered and unique //! guaranteed to be ordered and unique
struct ordered_unique_range_t struct ordered_unique_range_t
: public ordered_range_t : public ordered_range_t
{}; {};
//! Value used to tag that the input range is
//! guaranteed to be ordered
static const ordered_range_t ordered_range = ordered_range_t();
//! Value used to tag that the input range is //! Value used to tag that the input range is
//! guaranteed to be ordered and unique //! guaranteed to be ordered and unique
static const ordered_unique_range_t ordered_unique_range = ordered_unique_range_t(); static const ordered_unique_range_t ordered_unique_range = ordered_unique_range_t();
//! Type used to tag that the input range is
//! guaranteed to be ordered and unique
struct default_init_t
{};
//! Value used to tag that the input range is
//! guaranteed to be ordered and unique
static const default_init_t default_init = default_init_t();
/// @cond /// @cond
namespace detail_really_deep_namespace { namespace detail_really_deep_namespace {
@ -161,6 +169,7 @@ struct dummy
{ {
(void)ordered_range; (void)ordered_range;
(void)ordered_unique_range; (void)ordered_unique_range;
(void)default_init;
} }
}; };

View File

@ -13,7 +13,7 @@
#ifndef BOOST_CONTAINER_DETAIL_ALGORITHMS_HPP #ifndef BOOST_CONTAINER_DETAIL_ALGORITHMS_HPP
#define BOOST_CONTAINER_DETAIL_ALGORITHMS_HPP #define BOOST_CONTAINER_DETAIL_ALGORITHMS_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200) #if defined(_MSC_VER)
# pragma once # pragma once
#endif #endif
@ -35,13 +35,13 @@ namespace boost {
namespace container { namespace container {
template<class It> template<class It>
struct is_default_construct_iterator struct is_value_init_construct_iterator
{ {
static const bool value = false; static const bool value = false;
}; };
template<class U, class D> template<class U, class D>
struct is_default_construct_iterator<default_construct_iterator<U, D> > struct is_value_init_construct_iterator<value_init_construct_iterator<U, D> >
{ {
static const bool value = true; static const bool value = true;
}; };
@ -64,11 +64,17 @@ inline void construct_in_place(A &a, T* dest, InpIt source)
//#endif //#endif
template<class A, class T, class U, class D> template<class A, class T, class U, class D>
inline void construct_in_place(A &a, T *dest, default_construct_iterator<U, D>) inline void construct_in_place(A &a, T *dest, value_init_construct_iterator<U, D>)
{ {
boost::container::allocator_traits<A>::construct(a, dest); boost::container::allocator_traits<A>::construct(a, dest);
} }
template<class A, class T, class U, class D>
inline void construct_in_place(A &a, T *dest, default_init_construct_iterator<U, D>)
{
boost::container::allocator_traits<A>::construct(a, dest, default_init);
}
template<class A, class T, class U, class EF, class D> template<class A, class T, class U, class EF, class D>
inline void construct_in_place(A &a, T *dest, emplace_iterator<U, EF, D> ei) inline void construct_in_place(A &a, T *dest, emplace_iterator<U, EF, D> ei)
{ {

View File

@ -11,7 +11,7 @@
#ifndef BOOST_CONTAINER_ALLOCATION_TYPE_HPP #ifndef BOOST_CONTAINER_ALLOCATION_TYPE_HPP
#define BOOST_CONTAINER_ALLOCATION_TYPE_HPP #define BOOST_CONTAINER_ALLOCATION_TYPE_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200) #if defined(_MSC_VER)
# pragma once # pragma once
#endif #endif

View File

@ -11,7 +11,7 @@
#ifndef BOOST_CONTAINER_DETAIL_ALLOCATOR_VERSION_TRAITS_HPP #ifndef BOOST_CONTAINER_DETAIL_ALLOCATOR_VERSION_TRAITS_HPP
#define BOOST_CONTAINER_DETAIL_ALLOCATOR_VERSION_TRAITS_HPP #define BOOST_CONTAINER_DETAIL_ALLOCATOR_VERSION_TRAITS_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200) #if defined(_MSC_VER)
# pragma once # pragma once
#endif #endif
@ -92,8 +92,12 @@ struct allocator_version_traits<Allocator, 1>
static void deallocate_individual(Allocator &a, multiallocation_chain &holder) static void deallocate_individual(Allocator &a, multiallocation_chain &holder)
{ {
while(!holder.empty()){ size_type n = holder.size();
a.deallocate(holder.pop_front(), 1); typename multiallocation_chain::iterator it = holder.begin();
while(n--){
pointer p = boost::intrusive::pointer_traits<pointer>::pointer_to(*it);
++it;
a.deallocate(p, 1);
} }
} }

View File

@ -46,4 +46,5 @@
#pragma warning (disable : 4673) // throwing '' the following types will not be considered at the catch site #pragma warning (disable : 4673) // throwing '' the following types will not be considered at the catch site
#pragma warning (disable : 4671) // the copy constructor is inaccessible #pragma warning (disable : 4671) // the copy constructor is inaccessible
#pragma warning (disable : 4584) // X is already a base-class of Y #pragma warning (disable : 4584) // X is already a base-class of Y
#pragma warning (disable : 4510) // default constructor could not be generated
#endif //BOOST_MSVC #endif //BOOST_MSVC

View File

@ -13,7 +13,7 @@
#ifndef BOOST_CONTAINER_DESTROYERS_HPP #ifndef BOOST_CONTAINER_DESTROYERS_HPP
#define BOOST_CONTAINER_DESTROYERS_HPP #define BOOST_CONTAINER_DESTROYERS_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200) #if defined(_MSC_VER)
# pragma once # pragma once
#endif #endif
@ -68,6 +68,9 @@ struct scoped_deallocator
pointer get() const pointer get() const
{ return m_ptr; } { return m_ptr; }
void set(const pointer &p)
{ m_ptr = p; }
void release() void release()
{ m_ptr = 0; } { m_ptr = 0; }
}; };
@ -87,6 +90,9 @@ struct null_scoped_deallocator
pointer get() const pointer get() const
{ return pointer(); } { return pointer(); }
void set(const pointer &)
{}
}; };
//!A deleter for scoped_ptr that deallocates the memory //!A deleter for scoped_ptr that deallocates the memory
@ -249,6 +255,11 @@ class scoped_destructor
void release() void release()
{ pv_ = 0; } { pv_ = 0; }
void set(value_type *ptr) { pv_ = ptr; }
value_type *get() const { return pv_; }
private: private:
value_type *pv_; value_type *pv_;
A &a_; A &a_;

View File

@ -14,7 +14,7 @@
#ifndef BOOST_CONTAINER_DETAIL_ITERATORS_HPP #ifndef BOOST_CONTAINER_DETAIL_ITERATORS_HPP
#define BOOST_CONTAINER_DETAIL_ITERATORS_HPP #define BOOST_CONTAINER_DETAIL_ITERATORS_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200) #if defined(_MSC_VER)
# pragma once # pragma once
#endif #endif
@ -23,6 +23,7 @@
#include <boost/move/utility.hpp> #include <boost/move/utility.hpp>
#include <boost/container/allocator_traits.hpp> #include <boost/container/allocator_traits.hpp>
#include <boost/container/detail/type_traits.hpp> #include <boost/container/detail/type_traits.hpp>
#include <boost/static_assert.hpp>
#ifdef BOOST_CONTAINER_PERFECT_FORWARDING #ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#include <boost/container/detail/variadic_templates_tools.hpp> #include <boost/container/detail/variadic_templates_tools.hpp>
@ -147,79 +148,79 @@ class constant_iterator
}; };
template <class T, class Difference = std::ptrdiff_t> template <class T, class Difference = std::ptrdiff_t>
class default_construct_iterator class value_init_construct_iterator
: public std::iterator : public std::iterator
<std::random_access_iterator_tag, T, Difference, const T*, const T &> <std::random_access_iterator_tag, T, Difference, const T*, const T &>
{ {
typedef default_construct_iterator<T, Difference> this_type; typedef value_init_construct_iterator<T, Difference> this_type;
public: public:
explicit default_construct_iterator(Difference range_size) explicit value_init_construct_iterator(Difference range_size)
: m_num(range_size){} : m_num(range_size){}
//Constructors //Constructors
default_construct_iterator() value_init_construct_iterator()
: m_num(0){} : m_num(0){}
default_construct_iterator& operator++() value_init_construct_iterator& operator++()
{ increment(); return *this; } { increment(); return *this; }
default_construct_iterator operator++(int) value_init_construct_iterator operator++(int)
{ {
default_construct_iterator result (*this); value_init_construct_iterator result (*this);
increment(); increment();
return result; return result;
} }
default_construct_iterator& operator--() value_init_construct_iterator& operator--()
{ decrement(); return *this; } { decrement(); return *this; }
default_construct_iterator operator--(int) value_init_construct_iterator operator--(int)
{ {
default_construct_iterator result (*this); value_init_construct_iterator result (*this);
decrement(); decrement();
return result; return result;
} }
friend bool operator== (const default_construct_iterator& i, const default_construct_iterator& i2) friend bool operator== (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
{ return i.equal(i2); } { return i.equal(i2); }
friend bool operator!= (const default_construct_iterator& i, const default_construct_iterator& i2) friend bool operator!= (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
{ return !(i == i2); } { return !(i == i2); }
friend bool operator< (const default_construct_iterator& i, const default_construct_iterator& i2) friend bool operator< (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
{ return i.less(i2); } { return i.less(i2); }
friend bool operator> (const default_construct_iterator& i, const default_construct_iterator& i2) friend bool operator> (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
{ return i2 < i; } { return i2 < i; }
friend bool operator<= (const default_construct_iterator& i, const default_construct_iterator& i2) friend bool operator<= (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
{ return !(i > i2); } { return !(i > i2); }
friend bool operator>= (const default_construct_iterator& i, const default_construct_iterator& i2) friend bool operator>= (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
{ return !(i < i2); } { return !(i < i2); }
friend Difference operator- (const default_construct_iterator& i, const default_construct_iterator& i2) friend Difference operator- (const value_init_construct_iterator& i, const value_init_construct_iterator& i2)
{ return i2.distance_to(i); } { return i2.distance_to(i); }
//Arithmetic //Arithmetic
default_construct_iterator& operator+=(Difference off) value_init_construct_iterator& operator+=(Difference off)
{ this->advance(off); return *this; } { this->advance(off); return *this; }
default_construct_iterator operator+(Difference off) const value_init_construct_iterator operator+(Difference off) const
{ {
default_construct_iterator other(*this); value_init_construct_iterator other(*this);
other.advance(off); other.advance(off);
return other; return other;
} }
friend default_construct_iterator operator+(Difference off, const default_construct_iterator& right) friend value_init_construct_iterator operator+(Difference off, const value_init_construct_iterator& right)
{ return right + off; } { return right + off; }
default_construct_iterator& operator-=(Difference off) value_init_construct_iterator& operator-=(Difference off)
{ this->advance(-off); return *this; } { this->advance(-off); return *this; }
default_construct_iterator operator-(Difference off) const value_init_construct_iterator operator-(Difference off) const
{ return *this + (-off); } { return *this + (-off); }
//This pseudo-iterator's dereference operations have no sense since value is not //This pseudo-iterator's dereference operations have no sense since value is not
@ -257,6 +258,118 @@ class default_construct_iterator
{ return m_num - other.m_num; } { return m_num - other.m_num; }
}; };
template <class T, class Difference = std::ptrdiff_t>
class default_init_construct_iterator
: public std::iterator
<std::random_access_iterator_tag, T, Difference, const T*, const T &>
{
typedef default_init_construct_iterator<T, Difference> this_type;
public:
explicit default_init_construct_iterator(Difference range_size)
: m_num(range_size){}
//Constructors
default_init_construct_iterator()
: m_num(0){}
default_init_construct_iterator& operator++()
{ increment(); return *this; }
default_init_construct_iterator operator++(int)
{
default_init_construct_iterator result (*this);
increment();
return result;
}
default_init_construct_iterator& operator--()
{ decrement(); return *this; }
default_init_construct_iterator operator--(int)
{
default_init_construct_iterator result (*this);
decrement();
return result;
}
friend bool operator== (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
{ return i.equal(i2); }
friend bool operator!= (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
{ return !(i == i2); }
friend bool operator< (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
{ return i.less(i2); }
friend bool operator> (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
{ return i2 < i; }
friend bool operator<= (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
{ return !(i > i2); }
friend bool operator>= (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
{ return !(i < i2); }
friend Difference operator- (const default_init_construct_iterator& i, const default_init_construct_iterator& i2)
{ return i2.distance_to(i); }
//Arithmetic
default_init_construct_iterator& operator+=(Difference off)
{ this->advance(off); return *this; }
default_init_construct_iterator operator+(Difference off) const
{
default_init_construct_iterator other(*this);
other.advance(off);
return other;
}
friend default_init_construct_iterator operator+(Difference off, const default_init_construct_iterator& right)
{ return right + off; }
default_init_construct_iterator& operator-=(Difference off)
{ this->advance(-off); return *this; }
default_init_construct_iterator operator-(Difference off) const
{ return *this + (-off); }
//This pseudo-iterator's dereference operations have no sense since value is not
//constructed until ::boost::container::construct_in_place is called.
//So comment them to catch bad uses
//const T& operator*() const;
//const T& operator[](difference_type) const;
//const T* operator->() const;
private:
Difference m_num;
void increment()
{ --m_num; }
void decrement()
{ ++m_num; }
bool equal(const this_type &other) const
{ return m_num == other.m_num; }
bool less(const this_type &other) const
{ return other.m_num < m_num; }
const T & dereference() const
{
static T dummy;
return dummy;
}
void advance(Difference n)
{ m_num -= n; }
Difference distance_to(const this_type &other)const
{ return m_num - other.m_num; }
};
template <class T, class Difference = std::ptrdiff_t> template <class T, class Difference = std::ptrdiff_t>
class repeat_iterator class repeat_iterator
: public std::iterator : public std::iterator
@ -585,24 +698,112 @@ struct is_bidirectional_iterator<T, false>
static const bool value = false; static const bool value = false;
}; };
template<class T, class IIterator> template<class IIterator>
struct iiterator_types struct iiterator_types
{ {
typedef typename IIterator::value_type it_value_type;
typedef typename it_value_type::value_type value_type;
typedef typename std::iterator_traits<IIterator>::pointer it_pointer; typedef typename std::iterator_traits<IIterator>::pointer it_pointer;
typedef typename std::iterator_traits<IIterator>::difference_type difference_type; typedef typename std::iterator_traits<IIterator>::difference_type difference_type;
typedef typename ::boost::intrusive::pointer_traits<it_pointer>:: typedef typename ::boost::intrusive::pointer_traits<it_pointer>::
template rebind_pointer<T>::type pointer; template rebind_pointer<value_type>::type pointer;
typedef typename ::boost::intrusive::pointer_traits<it_pointer>:: typedef typename ::boost::intrusive::pointer_traits<it_pointer>::
template rebind_pointer<const T>::type const_pointer; template rebind_pointer<const value_type>::type const_pointer;
typedef typename ::boost::intrusive:: typedef typename ::boost::intrusive::
pointer_traits<pointer>::reference reference; pointer_traits<pointer>::reference reference;
typedef typename ::boost::intrusive:: typedef typename ::boost::intrusive::
pointer_traits<const_pointer>::reference const_reference; pointer_traits<const_pointer>::reference const_reference;
typedef typename IIterator::iterator_category iterator_category;
}; };
template<class IIterator, bool IsConst>
struct std_iterator
{
typedef typename std::iterator
< typename iiterator_types<IIterator>::iterator_category
, typename iiterator_types<IIterator>::value_type
, typename iiterator_types<IIterator>::difference_type
, typename iiterator_types<IIterator>::const_pointer
, typename iiterator_types<IIterator>::const_reference> type;
};
template<class IIterator>
struct std_iterator<IIterator, false>
{
typedef typename std::iterator
< typename iiterator_types<IIterator>::iterator_category
, typename iiterator_types<IIterator>::value_type
, typename iiterator_types<IIterator>::difference_type
, typename iiterator_types<IIterator>::pointer
, typename iiterator_types<IIterator>::reference> type;
};
template<class IIterator, bool IsConst>
class iterator
: public std_iterator<IIterator, IsConst>::type
{
typedef typename std_iterator<IIterator, IsConst>::type types_t;
public:
typedef typename types_t::value_type value_type;
typedef typename types_t::pointer pointer;
typedef typename types_t::reference reference;
iterator()
{}
explicit iterator(IIterator iit) BOOST_CONTAINER_NOEXCEPT
: m_iit(iit)
{}
iterator(iterator<IIterator, false> const& other) BOOST_CONTAINER_NOEXCEPT
: m_iit(other.get())
{}
iterator& operator++() BOOST_CONTAINER_NOEXCEPT
{ ++this->m_iit; return *this; }
iterator operator++(int) BOOST_CONTAINER_NOEXCEPT
{
iterator result (*this);
++this->m_iit;
return result;
}
iterator& operator--() BOOST_CONTAINER_NOEXCEPT
{
//If the iterator is not a bidirectional iterator, operator-- should not exist
BOOST_STATIC_ASSERT((is_bidirectional_iterator<iterator>::value));
--this->m_iit; return *this;
}
iterator operator--(int) BOOST_CONTAINER_NOEXCEPT
{
iterator result (*this);
--this->m_iit;
return result;
}
friend bool operator== (const iterator& l, const iterator& r) BOOST_CONTAINER_NOEXCEPT
{ return l.m_iit == r.m_iit; }
friend bool operator!= (const iterator& l, const iterator& r) BOOST_CONTAINER_NOEXCEPT
{ return !(l == r); }
reference operator*() const BOOST_CONTAINER_NOEXCEPT
{ return (*this->m_iit).get_data(); }
pointer operator->() const BOOST_CONTAINER_NOEXCEPT
{ return ::boost::intrusive::pointer_traits<pointer>::pointer_to(this->operator*()); }
const IIterator &get() const BOOST_CONTAINER_NOEXCEPT
{ return this->m_iit; }
private:
IIterator m_iit;
};
} //namespace container_detail { } //namespace container_detail {
} //namespace container { } //namespace container {
} //namespace boost { } //namespace boost {

View File

@ -11,7 +11,7 @@
#ifndef BOOST_CONTAINER_ALLOCATOR_MEMORY_UTIL_HPP #ifndef BOOST_CONTAINER_ALLOCATOR_MEMORY_UTIL_HPP
#define BOOST_CONTAINER_ALLOCATOR_MEMORY_UTIL_HPP #define BOOST_CONTAINER_ALLOCATOR_MEMORY_UTIL_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200) #if defined(_MSC_VER)
# pragma once # pragma once
#endif #endif

View File

@ -13,7 +13,7 @@
#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_MPL_HPP #ifndef BOOST_CONTAINER_CONTAINER_DETAIL_MPL_HPP
#define BOOST_CONTAINER_CONTAINER_DETAIL_MPL_HPP #define BOOST_CONTAINER_CONTAINER_DETAIL_MPL_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200) #if defined(_MSC_VER)
# pragma once # pragma once
#endif #endif

View File

@ -243,10 +243,10 @@ class transform_multiallocation_chain
iterator before_begin() iterator before_begin()
{ return iterator(holder_.before_begin()); } { return iterator(holder_.before_begin()); }
*/
iterator begin() iterator begin()
{ return iterator(holder_.begin()); } { return iterator(this->MultiallocationChain::begin()); }
/*
iterator end() iterator end()
{ return iterator(holder_.end()); } { return iterator(holder_.end()); }

View File

@ -11,7 +11,7 @@
#ifndef BOOST_CONTAINER_DETAIL_NODE_ALLOC_HPP_ #ifndef BOOST_CONTAINER_DETAIL_NODE_ALLOC_HPP_
#define BOOST_CONTAINER_DETAIL_NODE_ALLOC_HPP_ #define BOOST_CONTAINER_DETAIL_NODE_ALLOC_HPP_
#if (defined _MSC_VER) && (_MSC_VER >= 1200) #if defined(_MSC_VER)
# pragma once # pragma once
#endif #endif
@ -28,6 +28,7 @@
#include <boost/container/detail/type_traits.hpp> #include <boost/container/detail/type_traits.hpp>
#include <boost/container/detail/utilities.hpp> #include <boost/container/detail/utilities.hpp>
#include <boost/container/allocator_traits.hpp> #include <boost/container/allocator_traits.hpp>
#include <boost/container/detail/allocator_version_traits.hpp>
#include <boost/container/detail/mpl.hpp> #include <boost/container/detail/mpl.hpp>
#include <boost/container/detail/destroyers.hpp> #include <boost/container/detail/destroyers.hpp>
#include <boost/container/detail/allocator_version_traits.hpp> #include <boost/container/detail/allocator_version_traits.hpp>
@ -53,10 +54,14 @@ struct node_compare
typedef typename ValueCompare::value_type value_type; typedef typename ValueCompare::value_type value_type;
typedef typename ValueCompare::key_of_value key_of_value; typedef typename ValueCompare::key_of_value key_of_value;
node_compare(const ValueCompare &pred) explicit node_compare(const ValueCompare &pred)
: ValueCompare(pred) : ValueCompare(pred)
{} {}
node_compare()
: ValueCompare()
{}
ValueCompare &value_comp() ValueCompare &value_comp()
{ return static_cast<ValueCompare &>(*this); } { return static_cast<ValueCompare &>(*this); }
@ -67,16 +72,16 @@ struct node_compare
{ return ValueCompare::operator()(a.get_data(), b.get_data()); } { return ValueCompare::operator()(a.get_data(), b.get_data()); }
}; };
template<class A, class ICont, class Pred = container_detail::nat> template<class A, class ICont, class ValPred = container_detail::nat>
struct node_alloc_holder struct node_alloc_holder
{ {
typedef allocator_traits<A> allocator_traits_type; typedef allocator_traits<A> allocator_traits_type;
typedef node_alloc_holder<A, ICont> self_t;
typedef typename allocator_traits_type::value_type value_type; typedef typename allocator_traits_type::value_type value_type;
typedef typename ICont::value_type Node; typedef typename ICont::value_type Node;
typedef typename allocator_traits_type::template typedef typename allocator_traits_type::template
portable_rebind_alloc<Node>::type NodeAlloc; portable_rebind_alloc<Node>::type NodeAlloc;
typedef allocator_traits<NodeAlloc> node_allocator_traits_type; typedef allocator_traits<NodeAlloc> node_allocator_traits_type;
typedef container_detail::allocator_version_traits<NodeAlloc> node_allocator_version_traits_type;
typedef A ValAlloc; typedef A ValAlloc;
typedef typename node_allocator_traits_type::pointer NodePtr; typedef typename node_allocator_traits_type::pointer NodePtr;
typedef container_detail::scoped_deallocator<NodeAlloc> Deallocator; typedef container_detail::scoped_deallocator<NodeAlloc> Deallocator;
@ -116,20 +121,20 @@ struct node_alloc_holder
{ this->icont().swap(x.icont()); } { this->icont().swap(x.icont()); }
//Constructors for associative containers //Constructors for associative containers
explicit node_alloc_holder(const ValAlloc &a, const Pred &c) explicit node_alloc_holder(const ValAlloc &a, const ValPred &c)
: members_(a, c) : members_(a, c)
{} {}
explicit node_alloc_holder(const node_alloc_holder &x, const Pred &c) explicit node_alloc_holder(const node_alloc_holder &x, const ValPred &c)
: members_(NodeAllocTraits::select_on_container_copy_construction(x.node_alloc()), c) : members_(NodeAllocTraits::select_on_container_copy_construction(x.node_alloc()), c)
{} {}
explicit node_alloc_holder(const Pred &c) explicit node_alloc_holder(const ValPred &c)
: members_(c) : members_(c)
{} {}
//helpers for move assignments //helpers for move assignments
explicit node_alloc_holder(BOOST_RV_REF(node_alloc_holder) x, const Pred &c) explicit node_alloc_holder(BOOST_RV_REF(node_alloc_holder) x, const ValPred &c)
: members_(boost::move(x.node_alloc()), c) : members_(boost::move(x.node_alloc()), c)
{ this->icont().swap(x.icont()); } { this->icont().swap(x.icont()); }
@ -230,45 +235,41 @@ struct node_alloc_holder
(FwdIterator beg, difference_type n, Inserter inserter) (FwdIterator beg, difference_type n, Inserter inserter)
{ {
if(n){ if(n){
/* typedef typename node_allocator_version_traits_type::multiallocation_chain multiallocation_chain;
NodePtr p = this->allocate_one();
Deallocator node_deallocator(p, this->node_alloc());
::boost::container::construct_in_place(this->node_alloc(), container_detail::addressof(p->m_data), it);
node_deallocator.release();
//This does not throw
typedef typename Node::hook_type hook_type;
::new(static_cast<hook_type*>(container_detail::to_raw_pointer(p))) hook_type;
return (p);
*/
typedef typename NodeAlloc::multiallocation_chain multiallocation_chain;
//Try to allocate memory in a single block //Try to allocate memory in a single block
typedef typename multiallocation_chain::iterator multialloc_iterator; typedef typename multiallocation_chain::iterator multialloc_iterator;
multiallocation_chain mem; multiallocation_chain mem;
this->node_alloc().allocate_individual(n, mem); NodeAlloc &nalloc = this->node_alloc();
node_allocator_version_traits_type::allocate_individual(nalloc, n, mem);
multialloc_iterator itbeg(mem.begin()), itlast(mem.last()); multialloc_iterator itbeg(mem.begin()), itlast(mem.last());
mem.clear(); mem.clear();
Node *p = 0; Node *p = 0;
NodeAlloc &nalloc = this->node_alloc();
BOOST_TRY{ BOOST_TRY{
Deallocator node_deallocator(NodePtr(), nalloc);
container_detail::scoped_destructor<NodeAlloc> sdestructor(nalloc, 0);
while(n--){ while(n--){
p = container_detail::to_raw_pointer(&*itbeg); p = container_detail::to_raw_pointer(&*itbeg);
node_deallocator.set(p);
++itbeg; ++itbeg;
//This can throw //This can throw
Deallocator node_deallocator(p, nalloc);
boost::container::construct_in_place(nalloc, container_detail::addressof(p->m_data), beg); boost::container::construct_in_place(nalloc, container_detail::addressof(p->m_data), beg);
sdestructor.set(p);
++beg; ++beg;
node_deallocator.release();
//This does not throw //This does not throw
typedef typename Node::hook_type hook_type; typedef typename Node::hook_type hook_type;
::new(static_cast<hook_type*>(p)) hook_type; ::new(static_cast<hook_type*>(p)) hook_type;
//This can throw in some containers (predicate might throw) //This can throw in some containers (predicate might throw).
//(sdestructor will destruct the node and node_deallocator will deallocate it in case of exception)
inserter(*p); inserter(*p);
sdestructor.set(0);
} }
sdestructor.release();
node_deallocator.release();
} }
BOOST_CATCH(...){ BOOST_CATCH(...){
mem.incorporate_after(mem.last(), &*itbeg, &*itlast, n); mem.incorporate_after(mem.last(), &*itbeg, &*itlast, n);
this->node_alloc().deallocate_individual(mem); node_allocator_version_traits_type::deallocate_individual(this->node_alloc(), mem);
BOOST_RETHROW BOOST_RETHROW
} }
BOOST_CATCH_END BOOST_CATCH_END
@ -345,12 +346,12 @@ struct node_alloc_holder
{} {}
template<class ConvertibleToAlloc> template<class ConvertibleToAlloc>
members_holder(BOOST_FWD_REF(ConvertibleToAlloc) c2alloc, const Pred &c) members_holder(BOOST_FWD_REF(ConvertibleToAlloc) c2alloc, const ValPred &c)
: NodeAlloc(boost::forward<ConvertibleToAlloc>(c2alloc)) : NodeAlloc(boost::forward<ConvertibleToAlloc>(c2alloc))
, m_icont(typename ICont::value_compare(c)) , m_icont(typename ICont::value_compare(c))
{} {}
explicit members_holder(const Pred &c) explicit members_holder(const ValPred &c)
: NodeAlloc() : NodeAlloc()
, m_icont(typename ICont::value_compare(c)) , m_icont(typename ICont::value_compare(c))
{} {}

View File

@ -13,7 +13,7 @@
#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_PAIR_HPP #ifndef BOOST_CONTAINER_CONTAINER_DETAIL_PAIR_HPP
#define BOOST_CONTAINER_CONTAINER_DETAIL_PAIR_HPP #define BOOST_CONTAINER_CONTAINER_DETAIL_PAIR_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200) #if defined(_MSC_VER)
# pragma once # pragma once
#endif #endif

View File

@ -11,7 +11,7 @@
#ifndef BOOST_CONTAINER_DETAIL_PREPROCESSOR_HPP #ifndef BOOST_CONTAINER_DETAIL_PREPROCESSOR_HPP
#define BOOST_CONTAINER_DETAIL_PREPROCESSOR_HPP #define BOOST_CONTAINER_DETAIL_PREPROCESSOR_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200) #if defined(_MSC_VER)
# pragma once # pragma once
#endif #endif

View File

@ -14,7 +14,7 @@
#ifndef BOOST_CONTAINER_DETAIL_TRANSFORM_ITERATORS_HPP #ifndef BOOST_CONTAINER_DETAIL_TRANSFORM_ITERATORS_HPP
#define BOOST_CONTAINER_DETAIL_TRANSFORM_ITERATORS_HPP #define BOOST_CONTAINER_DETAIL_TRANSFORM_ITERATORS_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200) #if defined(_MSC_VER)
# pragma once # pragma once
#endif #endif

View File

@ -20,8 +20,8 @@
#include <boost/type_traits/has_trivial_destructor.hpp> #include <boost/type_traits/has_trivial_destructor.hpp>
#include <boost/detail/no_exceptions_support.hpp> #include <boost/detail/no_exceptions_support.hpp>
#include <boost/intrusive/rbtree.hpp> #include <boost/intrusive/rbtree.hpp>
#include <boost/container/detail/utilities.hpp> #include <boost/container/detail/utilities.hpp>
#include <boost/container/detail/iterators.hpp>
#include <boost/container/detail/algorithms.hpp> #include <boost/container/detail/algorithms.hpp>
#include <boost/container/detail/node_alloc_holder.hpp> #include <boost/container/detail/node_alloc_holder.hpp>
#include <boost/container/detail/destroyers.hpp> #include <boost/container/detail/destroyers.hpp>
@ -50,8 +50,12 @@ struct tree_value_compare
typedef KeyOfValue key_of_value; typedef KeyOfValue key_of_value;
typedef Key key_type; typedef Key key_type;
tree_value_compare(const key_compare &kcomp) explicit tree_value_compare(const key_compare &kcomp)
: key_compare(kcomp) : KeyCompare(kcomp)
{}
tree_value_compare()
: KeyCompare()
{} {}
const key_compare &key_comp() const const key_compare &key_comp() const
@ -174,6 +178,34 @@ struct rbtree_node
{ m_data = ::boost::move(v); } { m_data = ::boost::move(v); }
}; };
template<class Node, class Icont>
class insert_equal_end_hint_functor
{
Icont &icont_;
public:
insert_equal_end_hint_functor(Icont &icont)
: icont_(icont)
{}
void operator()(Node &n)
{ this->icont_.insert_equal(this->icont_.cend(), n); }
};
template<class Node, class Icont>
class push_back_functor
{
Icont &icont_;
public:
push_back_functor(Icont &icont)
: icont_(icont)
{}
void operator()(Node &n)
{ this->icont_.push_back(n); }
};
}//namespace container_detail { }//namespace container_detail {
namespace container_detail { namespace container_detail {
@ -212,15 +244,15 @@ class rbtree
, typename container_detail::intrusive_rbtree_type , typename container_detail::intrusive_rbtree_type
<A, tree_value_compare<Key, Value, KeyCompare, KeyOfValue> <A, tree_value_compare<Key, Value, KeyCompare, KeyOfValue>
>::type >::type
, KeyCompare , tree_value_compare<Key, Value, KeyCompare, KeyOfValue>
> >
{ {
typedef tree_value_compare
<Key, Value, KeyCompare, KeyOfValue> ValComp;
typedef typename container_detail::intrusive_rbtree_type typedef typename container_detail::intrusive_rbtree_type
< A, tree_value_compare < A, ValComp>::type Icont;
<Key, Value, KeyCompare, KeyOfValue>
>::type Icont;
typedef container_detail::node_alloc_holder typedef container_detail::node_alloc_holder
<A, Icont, KeyCompare> AllocHolder; <A, Icont, ValComp> AllocHolder;
typedef typename AllocHolder::NodePtr NodePtr; typedef typename AllocHolder::NodePtr NodePtr;
typedef rbtree < Key, Value, KeyOfValue typedef rbtree < Key, Value, KeyOfValue
, KeyCompare, A> ThisType; , KeyCompare, A> ThisType;
@ -318,8 +350,7 @@ class rbtree
typedef Value value_type; typedef Value value_type;
typedef A allocator_type; typedef A allocator_type;
typedef KeyCompare key_compare; typedef KeyCompare key_compare;
typedef tree_value_compare< Key, Value typedef ValComp value_compare;
, KeyCompare, KeyOfValue> value_compare;
typedef typename boost::container:: typedef typename boost::container::
allocator_traits<A>::pointer pointer; allocator_traits<A>::pointer pointer;
typedef typename boost::container:: typedef typename boost::container::
@ -373,109 +404,21 @@ class rbtree
typedef key_node_compare<value_compare> KeyNodeCompare; typedef key_node_compare<value_compare> KeyNodeCompare;
public: public:
//rbtree const_iterator typedef container_detail::iterator<iiterator, false> iterator;
class const_iterator typedef container_detail::iterator<iiterator, true > const_iterator;
: public std::iterator
< std::bidirectional_iterator_tag
, value_type , rbtree_difference_type
, rbtree_const_pointer , rbtree_const_reference>
{
protected:
typedef typename Icont::iterator iiterator;
iiterator m_it;
explicit const_iterator(iiterator it) : m_it(it){}
void prot_incr() { ++m_it; }
void prot_decr() { --m_it; }
private:
iiterator get()
{ return this->m_it; }
public:
friend class rbtree <Key, Value, KeyOfValue, KeyCompare, A>;
typedef rbtree_difference_type difference_type;
//Constructors
const_iterator()
: m_it()
{}
//Pointer like operators
const_reference operator*() const
{ return m_it->get_data(); }
const_pointer operator->() const
{ return const_pointer(&m_it->get_data()); }
//Increment / Decrement
const_iterator& operator++()
{ prot_incr(); return *this; }
const_iterator operator++(int)
{ iiterator tmp = m_it; ++*this; return const_iterator(tmp); }
const_iterator& operator--()
{ prot_decr(); return *this; }
const_iterator operator--(int)
{ iiterator tmp = m_it; --*this; return const_iterator(tmp); }
//Comparison operators
bool operator== (const const_iterator& r) const
{ return m_it == r.m_it; }
bool operator!= (const const_iterator& r) const
{ return m_it != r.m_it; }
};
//rbtree iterator
class iterator : public const_iterator
{
private:
explicit iterator(iiterator it)
: const_iterator(it)
{}
iiterator get()
{ return this->m_it; }
public:
friend class rbtree <Key, Value, KeyOfValue, KeyCompare, A>;
typedef rbtree_pointer pointer;
typedef rbtree_reference reference;
//Constructors
iterator(){}
//Pointer like operators
reference operator*() const
{ return this->m_it->get_data(); }
pointer operator->() const
{ return boost::intrusive::pointer_traits<pointer>::pointer_to(this->m_it->get_data()); }
//Increment / Decrement
iterator& operator++()
{ this->prot_incr(); return *this; }
iterator operator++(int)
{ iiterator tmp = this->m_it; ++*this; return iterator(tmp); }
iterator& operator--()
{ this->prot_decr(); return *this; }
iterator operator--(int)
{ iterator tmp = *this; --*this; return tmp; }
};
typedef std::reverse_iterator<iterator> reverse_iterator; typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator; typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
rbtree() rbtree()
: AllocHolder(key_compare()) : AllocHolder(ValComp(key_compare()))
{} {}
rbtree(const key_compare& comp, const allocator_type& a = allocator_type()) explicit rbtree(const key_compare& comp, const allocator_type& a = allocator_type())
: AllocHolder(a, comp) : AllocHolder(a, ValComp(comp))
{}
explicit rbtree(const allocator_type& a)
: AllocHolder(a)
{} {}
template <class InputIterator> template <class InputIterator>
@ -488,13 +431,21 @@ class rbtree
>::type * = 0 >::type * = 0
#endif #endif
) )
: AllocHolder(a, comp) : AllocHolder(a, value_compare(comp))
{ {
//Use cend() as hint to achieve linear time for
//ordered ranges as required by the standard
//for the constructor
const const_iterator end_it(this->cend());
if(unique_insertion){ if(unique_insertion){
this->insert_unique(first, last); for ( ; first != last; ++first){
this->insert_unique(end_it, *first);
}
} }
else{ else{
this->insert_equal(first, last); for ( ; first != last; ++first){
this->insert_equal(end_it, *first);
}
} }
} }
@ -508,15 +459,22 @@ class rbtree
>::type * = 0 >::type * = 0
#endif #endif
) )
: AllocHolder(a, comp) : AllocHolder(a, value_compare(comp))
{ {
if(unique_insertion){ if(unique_insertion){
this->insert_unique(first, last); //Use cend() as hint to achieve linear time for
//ordered ranges as required by the standard
//for the constructor
const const_iterator end_it(this->cend());
for ( ; first != last; ++first){
this->insert_unique(end_it, *first);
}
} }
else{ else{
//Optimized allocation and construction //Optimized allocation and construction
this->allocate_many_and_construct this->allocate_many_and_construct
(first, std::distance(first, last), insert_equal_end_hint_functor(this->icont())); ( first, std::distance(first, last)
, insert_equal_end_hint_functor<Node, Icont>(this->icont()));
} }
} }
@ -530,9 +488,11 @@ class rbtree
>::type * = 0 >::type * = 0
#endif #endif
) )
: AllocHolder(a, comp) : AllocHolder(a, value_compare(comp))
{ {
this->insert_equal(first, last); for ( ; first != last; ++first){
this->push_back_impl(*first);
}
} }
template <class InputIterator> template <class InputIterator>
@ -545,33 +505,34 @@ class rbtree
>::type * = 0 >::type * = 0
#endif #endif
) )
: AllocHolder(a, comp) : AllocHolder(a, value_compare(comp))
{ {
//Optimized allocation and construction //Optimized allocation and construction
this->allocate_many_and_construct this->allocate_many_and_construct
(first, std::distance(first, last), push_back_functor(this->icont())); ( first, std::distance(first, last)
, container_detail::push_back_functor<Node, Icont>(this->icont()));
} }
rbtree(const rbtree& x) rbtree(const rbtree& x)
: AllocHolder(x, x.key_comp()) : AllocHolder(x, x.value_comp())
{ {
this->icont().clone_from this->icont().clone_from
(x.icont(), typename AllocHolder::cloner(*this), Destroyer(this->node_alloc())); (x.icont(), typename AllocHolder::cloner(*this), Destroyer(this->node_alloc()));
} }
rbtree(BOOST_RV_REF(rbtree) x) rbtree(BOOST_RV_REF(rbtree) x)
: AllocHolder(::boost::move(static_cast<AllocHolder&>(x)), x.key_comp()) : AllocHolder(::boost::move(static_cast<AllocHolder&>(x)), x.value_comp())
{} {}
rbtree(const rbtree& x, const allocator_type &a) rbtree(const rbtree& x, const allocator_type &a)
: AllocHolder(a, x.key_comp()) : AllocHolder(a, x.value_comp())
{ {
this->icont().clone_from this->icont().clone_from
(x.icont(), typename AllocHolder::cloner(*this), Destroyer(this->node_alloc())); (x.icont(), typename AllocHolder::cloner(*this), Destroyer(this->node_alloc()));
} }
rbtree(BOOST_RV_REF(rbtree) x, const allocator_type &a) rbtree(BOOST_RV_REF(rbtree) x, const allocator_type &a)
: AllocHolder(a, x.key_comp()) : AllocHolder(a, x.value_comp())
{ {
if(this->node_alloc() == x.node_alloc()){ if(this->node_alloc() == x.node_alloc()){
this->icont().swap(x.icont()); this->icont().swap(x.icont());
@ -619,8 +580,8 @@ class rbtree
rbtree& operator=(BOOST_RV_REF(rbtree) x) rbtree& operator=(BOOST_RV_REF(rbtree) x)
{ {
if (&x != this){ if (&x != this){
NodeAlloc &this_alloc = this->node_alloc(); NodeAlloc &this_alloc = this->get_stored_allocator();
NodeAlloc &x_alloc = x.node_alloc(); const NodeAlloc &x_alloc = x.get_stored_allocator();
//If allocators are equal we can just swap pointers //If allocators are equal we can just swap pointers
if(this_alloc == x_alloc){ if(this_alloc == x_alloc){
//Destroy and swap pointers //Destroy and swap pointers
@ -763,8 +724,10 @@ class rbtree
iterator insert_unique_commit(const value_type& v, insert_commit_data &data) iterator insert_unique_commit(const value_type& v, insert_commit_data &data)
{ {
NodePtr tmp = AllocHolder::create_node(v); NodePtr tmp = AllocHolder::create_node(v);
iiterator it(this->icont().insert_unique_commit(*tmp, data)); scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
return iterator(it); iterator ret(this->icont().insert_unique_commit(*tmp, data));
destroy_deallocator.release();
return ret;
} }
template<class MovableConvertible> template<class MovableConvertible>
@ -772,8 +735,10 @@ class rbtree
(BOOST_FWD_REF(MovableConvertible) mv, insert_commit_data &data) (BOOST_FWD_REF(MovableConvertible) mv, insert_commit_data &data)
{ {
NodePtr tmp = AllocHolder::create_node(boost::forward<MovableConvertible>(mv)); NodePtr tmp = AllocHolder::create_node(boost::forward<MovableConvertible>(mv));
iiterator it(this->icont().insert_unique_commit(*tmp, data)); scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
return iterator(it); iterator ret(this->icont().insert_unique_commit(*tmp, data));
destroy_deallocator.release();
return ret;
} }
std::pair<iterator,bool> insert_unique(const value_type& v) std::pair<iterator,bool> insert_unique(const value_type& v)
@ -781,10 +746,10 @@ class rbtree
insert_commit_data data; insert_commit_data data;
std::pair<iterator,bool> ret = std::pair<iterator,bool> ret =
this->insert_unique_check(KeyOfValue()(v), data); this->insert_unique_check(KeyOfValue()(v), data);
if(!ret.second) if(ret.second){
ret.first = this->insert_unique_commit(v, data);
}
return ret; return ret;
return std::pair<iterator,bool>
(this->insert_unique_commit(v, data), true);
} }
template<class MovableConvertible> template<class MovableConvertible>
@ -793,13 +758,22 @@ class rbtree
insert_commit_data data; insert_commit_data data;
std::pair<iterator,bool> ret = std::pair<iterator,bool> ret =
this->insert_unique_check(KeyOfValue()(mv), data); this->insert_unique_check(KeyOfValue()(mv), data);
if(!ret.second) if(ret.second){
ret.first = this->insert_unique_commit(boost::forward<MovableConvertible>(mv), data);
}
return ret; return ret;
return std::pair<iterator,bool>
(this->insert_unique_commit(boost::forward<MovableConvertible>(mv), data), true);
} }
private: private:
template<class MovableConvertible>
void push_back_impl(BOOST_FWD_REF(MovableConvertible) mv)
{
NodePtr tmp(AllocHolder::create_node(boost::forward<MovableConvertible>(mv)));
//push_back has no-throw guarantee so avoid any deallocator/destroyer
this->icont().push_back(*tmp);
}
std::pair<iterator, bool> emplace_unique_impl(NodePtr p) std::pair<iterator, bool> emplace_unique_impl(NodePtr p)
{ {
value_type &v = p->get_data(); value_type &v = p->get_data();
@ -845,15 +819,21 @@ class rbtree
template <class... Args> template <class... Args>
iterator emplace_equal(Args&&... args) iterator emplace_equal(Args&&... args)
{ {
NodePtr p(AllocHolder::create_node(boost::forward<Args>(args)...)); NodePtr tmp(AllocHolder::create_node(boost::forward<Args>(args)...));
return iterator(this->icont().insert_equal(this->icont().end(), *p)); scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
iterator ret(this->icont().insert_equal(this->icont().end(), *tmp));
destroy_deallocator.release();
return ret;
} }
template <class... Args> template <class... Args>
iterator emplace_hint_equal(const_iterator hint, Args&&... args) iterator emplace_hint_equal(const_iterator hint, Args&&... args)
{ {
NodePtr p(AllocHolder::create_node(boost::forward<Args>(args)...)); NodePtr tmp(AllocHolder::create_node(boost::forward<Args>(args)...));
return iterator(this->icont().insert_equal(hint.get(), *p)); scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
iterator ret(this->icont().insert_equal(hint.get(), *tmp));
destroy_deallocator.release();
return ret;
} }
#else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING #else //#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
@ -877,16 +857,22 @@ class rbtree
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
iterator emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ iterator emplace_equal(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ \ { \
NodePtr p(AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \ NodePtr tmp(AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \
return iterator(this->icont().insert_equal(this->icont().end(), *p)); \ scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc()); \
iterator ret(this->icont().insert_equal(this->icont().end(), *tmp)); \
destroy_deallocator.release(); \
return ret; \
} \ } \
\ \
BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \ BOOST_PP_EXPR_IF(n, template<) BOOST_PP_ENUM_PARAMS(n, class P) BOOST_PP_EXPR_IF(n, >) \
iterator emplace_hint_equal(const_iterator hint \ iterator emplace_hint_equal(const_iterator hint \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \ BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ \ { \
NodePtr p(AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \ NodePtr tmp(AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \
return iterator(this->icont().insert_equal(hint.get(), *p)); \ scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc()); \
iterator ret(this->icont().insert_equal(hint.get(), *tmp)); \
destroy_deallocator.release(); \
return ret; \
} \ } \
//! //!
#define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS) #define BOOST_PP_LOCAL_LIMITS (0, BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS)
@ -918,53 +904,53 @@ class rbtree
template <class InputIterator> template <class InputIterator>
void insert_unique(InputIterator first, InputIterator last) void insert_unique(InputIterator first, InputIterator last)
{ {
if(this->empty()){
//Insert with end hint, to achieve linear
//complexity if [first, last) is ordered
const_iterator hint(this->cend());
for( ; first != last; ++first)
hint = this->insert_unique(hint, *first);
}
else{
for( ; first != last; ++first) for( ; first != last; ++first)
this->insert_unique(*first); this->insert_unique(*first);
} }
}
iterator insert_equal(const value_type& v) iterator insert_equal(const value_type& v)
{ {
NodePtr p(AllocHolder::create_node(v)); NodePtr tmp(AllocHolder::create_node(v));
return iterator(this->icont().insert_equal(this->icont().end(), *p)); scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
iterator ret(this->icont().insert_equal(this->icont().end(), *tmp));
destroy_deallocator.release();
return ret;
} }
template<class MovableConvertible> template<class MovableConvertible>
iterator insert_equal(BOOST_FWD_REF(MovableConvertible) mv) iterator insert_equal(BOOST_FWD_REF(MovableConvertible) mv)
{ {
NodePtr p(AllocHolder::create_node(boost::forward<MovableConvertible>(mv))); NodePtr tmp(AllocHolder::create_node(boost::forward<MovableConvertible>(mv)));
return iterator(this->icont().insert_equal(this->icont().end(), *p)); scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
iterator ret(this->icont().insert_equal(this->icont().end(), *tmp));
destroy_deallocator.release();
return ret;
} }
iterator insert_equal(const_iterator hint, const value_type& v) iterator insert_equal(const_iterator hint, const value_type& v)
{ {
NodePtr p(AllocHolder::create_node(v)); NodePtr tmp(AllocHolder::create_node(v));
return iterator(this->icont().insert_equal(hint.get(), *p)); scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
iterator ret(this->icont().insert_equal(hint.get(), *tmp));
destroy_deallocator.release();
return ret;
} }
template<class MovableConvertible> template<class MovableConvertible>
iterator insert_equal(const_iterator hint, BOOST_FWD_REF(MovableConvertible) mv) iterator insert_equal(const_iterator hint, BOOST_FWD_REF(MovableConvertible) mv)
{ {
NodePtr p(AllocHolder::create_node(boost::forward<MovableConvertible>(mv))); NodePtr tmp(AllocHolder::create_node(boost::forward<MovableConvertible>(mv)));
return iterator(this->icont().insert_equal(hint.get(), *p)); scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
iterator ret(this->icont().insert_equal(hint.get(), *tmp));
destroy_deallocator.release();
return ret;
} }
template <class InputIterator> template <class InputIterator>
void insert_equal(InputIterator first, InputIterator last) void insert_equal(InputIterator first, InputIterator last)
{ {
//Insert with end hint, to achieve linear
//complexity if [first, last) is ordered
const_iterator hint(this->cend());
for( ; first != last; ++first) for( ; first != last; ++first)
hint = this->insert_equal(hint, *first); this->insert_equal(*first);
} }
iterator erase(const_iterator position) iterator erase(const_iterator position)
@ -1015,41 +1001,6 @@ class rbtree
return std::pair<const_iterator,const_iterator> return std::pair<const_iterator,const_iterator>
(const_iterator(ret.first), const_iterator(ret.second)); (const_iterator(ret.first), const_iterator(ret.second));
} }
private:
class insert_equal_end_hint_functor;
friend class insert_equal_end_hint_functor;
class insert_equal_end_hint_functor
{
Icont &icont_;
const iconst_iterator cend_;
public:
insert_equal_end_hint_functor(Icont &icont)
: icont_(icont), cend_(this->icont_.cend())
{}
void operator()(Node &n)
{ this->icont_.insert_equal(cend_, n); }
};
class push_back_functor;
friend class push_back_functor;
class push_back_functor
{
Icont &icont_;
public:
push_back_functor(Icont &icont)
: icont_(icont)
{}
void operator()(Node &n)
{ this->icont_.push_back(n); }
};
}; };
template <class Key, class Value, class KeyOfValue, template <class Key, class Value, class KeyOfValue,

View File

@ -15,7 +15,7 @@
#ifndef BOOST_CONTAINER_CONTAINER_DETAIL_TYPE_TRAITS_HPP #ifndef BOOST_CONTAINER_CONTAINER_DETAIL_TYPE_TRAITS_HPP
#define BOOST_CONTAINER_CONTAINER_DETAIL_TYPE_TRAITS_HPP #define BOOST_CONTAINER_CONTAINER_DETAIL_TYPE_TRAITS_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200) #if defined(_MSC_VER)
# pragma once # pragma once
#endif #endif

View File

@ -12,6 +12,7 @@
#define BOOST_CONTAINER_DETAIL_UTILITIES_HPP #define BOOST_CONTAINER_DETAIL_UTILITIES_HPP
#include "config_begin.hpp" #include "config_begin.hpp"
#include "workaround.hpp"
#include <cstdio> #include <cstdio>
#include <cstring> //for ::memcpy #include <cstring> //for ::memcpy
#include <boost/type_traits/is_fundamental.hpp> #include <boost/type_traits/is_fundamental.hpp>
@ -621,7 +622,7 @@ inline typename container_detail::enable_if_memcpy_copy_constructible<I, F, I>::
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// //
// uninitialized_default_alloc_n // uninitialized_value_init_alloc_n
// //
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
@ -635,7 +636,7 @@ inline typename container_detail::enable_if_memcpy_copy_constructible<I, F, I>::
template template
<typename A, <typename A,
typename F> // F models ForwardIterator typename F> // F models ForwardIterator
inline F uninitialized_default_alloc_n(A &a, typename allocator_traits<A>::difference_type n, F r) inline F uninitialized_value_init_alloc_n(A &a, typename allocator_traits<A>::difference_type n, F r)
{ {
F back = r; F back = r;
BOOST_TRY{ BOOST_TRY{
@ -654,6 +655,41 @@ inline F uninitialized_default_alloc_n(A &a, typename allocator_traits<A>::diffe
return r; return r;
} }
//////////////////////////////////////////////////////////////////////////////
//
// uninitialized_default_init_alloc_n
//
//////////////////////////////////////////////////////////////////////////////
//! <b>Effects</b>:
//! \code
//! for (; n--; ++r, ++f)
//! allocator_traits::construct(a, &*r);
//! \endcode
//!
//! <b>Returns</b>: r
template
<typename A,
typename F> // F models ForwardIterator
inline F uninitialized_default_init_alloc_n(A &a, typename allocator_traits<A>::difference_type n, F r)
{
F back = r;
BOOST_TRY{
while (n--) {
allocator_traits<A>::construct(a, container_detail::to_raw_pointer(&*r), default_init);
++r;
}
}
BOOST_CATCH(...){
for (; back != r; ++back){
allocator_traits<A>::destroy(a, container_detail::to_raw_pointer(&*back));
}
BOOST_RETHROW;
}
BOOST_CATCH_END
return r;
}
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////
// //
// uninitialized_fill_alloc // uninitialized_fill_alloc
@ -1055,18 +1091,21 @@ inline typename container_detail::enable_if_c
::memcpy(short_ptr, stora_ptr, sizeof_storage); ::memcpy(short_ptr, stora_ptr, sizeof_storage);
large_ptr += sizeof_storage; large_ptr += sizeof_storage;
short_ptr += sizeof_storage; short_ptr += sizeof_storage;
BOOST_CONTAINER_FALLTHOUGH
case 3: case 3:
::memcpy(stora_ptr, large_ptr, sizeof_storage); ::memcpy(stora_ptr, large_ptr, sizeof_storage);
::memcpy(large_ptr, short_ptr, sizeof_storage); ::memcpy(large_ptr, short_ptr, sizeof_storage);
::memcpy(short_ptr, stora_ptr, sizeof_storage); ::memcpy(short_ptr, stora_ptr, sizeof_storage);
large_ptr += sizeof_storage; large_ptr += sizeof_storage;
short_ptr += sizeof_storage; short_ptr += sizeof_storage;
BOOST_CONTAINER_FALLTHOUGH
case 2: case 2:
::memcpy(stora_ptr, large_ptr, sizeof_storage); ::memcpy(stora_ptr, large_ptr, sizeof_storage);
::memcpy(large_ptr, short_ptr, sizeof_storage); ::memcpy(large_ptr, short_ptr, sizeof_storage);
::memcpy(short_ptr, stora_ptr, sizeof_storage); ::memcpy(short_ptr, stora_ptr, sizeof_storage);
large_ptr += sizeof_storage; large_ptr += sizeof_storage;
short_ptr += sizeof_storage; short_ptr += sizeof_storage;
BOOST_CONTAINER_FALLTHOUGH
case 1: case 1:
::memcpy(stora_ptr, large_ptr, sizeof_storage); ::memcpy(stora_ptr, large_ptr, sizeof_storage);
::memcpy(large_ptr, short_ptr, sizeof_storage); ::memcpy(large_ptr, short_ptr, sizeof_storage);

View File

@ -13,7 +13,7 @@
#ifndef BOOST_CONTAINER_DETAIL_VALUE_INIT_HPP #ifndef BOOST_CONTAINER_DETAIL_VALUE_INIT_HPP
#define BOOST_CONTAINER_DETAIL_VALUE_INIT_HPP #define BOOST_CONTAINER_DETAIL_VALUE_INIT_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200) #if defined(_MSC_VER)
# pragma once # pragma once
#endif #endif

View File

@ -11,7 +11,7 @@
#ifndef BOOST_CONTAINER_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP #ifndef BOOST_CONTAINER_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP
#define BOOST_CONTAINER_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP #define BOOST_CONTAINER_DETAIL_VARIADIC_TEMPLATES_TOOLS_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200) #if defined(_MSC_VER)
# pragma once # pragma once
#endif #endif

View File

@ -35,6 +35,12 @@
#define BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST #define BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST
#endif #endif
#if !defined(BOOST_FALLTHOUGH)
#define BOOST_CONTAINER_FALLTHOUGH
#else
#define BOOST_CONTAINER_FALLTHOUGH BOOST_FALLTHOUGH;
#endif
//Macros for documentation purposes. For code, expands to the argument //Macros for documentation purposes. For code, expands to the argument
#define BOOST_CONTAINER_IMPDEF(TYPE) TYPE #define BOOST_CONTAINER_IMPDEF(TYPE) TYPE
#define BOOST_CONTAINER_SEEDOC(TYPE) TYPE #define BOOST_CONTAINER_SEEDOC(TYPE) TYPE

View File

@ -11,7 +11,7 @@
#ifndef BOOST_CONTAINER_MAP_HPP #ifndef BOOST_CONTAINER_MAP_HPP
#define BOOST_CONTAINER_MAP_HPP #define BOOST_CONTAINER_MAP_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200) #if defined(_MSC_VER)
# pragma once # pragma once
#endif #endif
@ -138,6 +138,16 @@ class map
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value)); BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
} }
//! <b>Effects</b>: Constructs an empty map using the specified allocator.
//!
//! <b>Complexity</b>: Constant.
explicit map(const allocator_type& a)
: m_tree(a)
{
//Allocator type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
}
//! <b>Effects</b>: Constructs an empty map using the specified comparison object and //! <b>Effects</b>: Constructs an empty map using the specified comparison object and
//! allocator, and inserts elements from the range [first ,last ). //! allocator, and inserts elements from the range [first ,last ).
//! //!
@ -160,6 +170,8 @@ class map
//! unique values. //! unique values.
//! //!
//! <b>Complexity</b>: Linear in N. //! <b>Complexity</b>: Linear in N.
//!
//! <b>Note</b>: Non-standard extension.
template <class InputIterator> template <class InputIterator>
map( ordered_unique_range_t, InputIterator first, InputIterator last map( ordered_unique_range_t, InputIterator first, InputIterator last
, const Compare& comp = Compare(), const allocator_type& a = allocator_type()) , const Compare& comp = Compare(), const allocator_type& a = allocator_type())
@ -701,7 +713,7 @@ class map
//! //!
//! <b>Complexity</b>: log(size())+count(k) //! <b>Complexity</b>: log(size())+count(k)
size_type count(const key_type& x) const size_type count(const key_type& x) const
{ return m_tree.find(x) == m_tree.end() ? 0 : 1; } { return static_cast<size_type>(m_tree.find(x) != m_tree.end()); }
//! <b>Returns</b>: An iterator pointing to the first element with key not less //! <b>Returns</b>: An iterator pointing to the first element with key not less
//! than k, or a.end() if such an element is not found. //! than k, or a.end() if such an element is not found.
@ -918,8 +930,7 @@ class multimap
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value)); BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
} }
//! <b>Effects</b>: Constructs an empty multimap using the specified comparison //! <b>Effects</b>: Constructs an empty multimap using the specified allocator.
//! object and allocator.
//! //!
//! <b>Complexity</b>: Constant. //! <b>Complexity</b>: Constant.
explicit multimap(const Compare& comp, const allocator_type& a = allocator_type()) explicit multimap(const Compare& comp, const allocator_type& a = allocator_type())
@ -929,6 +940,17 @@ class multimap
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value)); BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
} }
//! <b>Effects</b>: Constructs an empty multimap using the specified comparison
//! object and allocator.
//!
//! <b>Complexity</b>: Constant.
explicit multimap(const allocator_type& a)
: m_tree(a)
{
//Allocator type must be std::pair<CONST Key, T>
BOOST_STATIC_ASSERT((container_detail::is_same<std::pair<const Key, T>, typename Allocator::value_type>::value));
}
//! <b>Effects</b>: Constructs an empty multimap using the specified comparison object //! <b>Effects</b>: Constructs an empty multimap using the specified comparison object
//! and allocator, and inserts elements from the range [first ,last ). //! and allocator, and inserts elements from the range [first ,last ).
//! //!
@ -951,6 +973,8 @@ class multimap
//! <b>Requires</b>: [first ,last) must be ordered according to the predicate. //! <b>Requires</b>: [first ,last) must be ordered according to the predicate.
//! //!
//! <b>Complexity</b>: Linear in N. //! <b>Complexity</b>: Linear in N.
//!
//! <b>Note</b>: Non-standard extension.
template <class InputIterator> template <class InputIterator>
multimap(ordered_range_t, InputIterator first, InputIterator last, const Compare& comp = Compare(), multimap(ordered_range_t, InputIterator first, InputIterator last, const Compare& comp = Compare(),
const allocator_type& a = allocator_type()) const allocator_type& a = allocator_type())

View File

@ -17,7 +17,7 @@
#ifndef BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_HPP #ifndef BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_HPP
#define BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_HPP #define BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_HPP
#if (defined MSC_VER) && (_MSC_VER >= 1200) #if defined (_MSC_VER)
# pragma once # pragma once
#endif #endif
@ -585,6 +585,8 @@ class scoped_allocator_adaptor_base
typedef OuterAlloc outer_allocator_type; typedef OuterAlloc outer_allocator_type;
typedef scoped_allocator_adaptor<InnerAllocs...> inner_allocator_type; typedef scoped_allocator_adaptor<InnerAllocs...> inner_allocator_type;
typedef allocator_traits<inner_allocator_type> inner_traits_type; typedef allocator_traits<inner_allocator_type> inner_traits_type;
typedef scoped_allocator_adaptor
<OuterAlloc, InnerAllocs...> scoped_allocator_type;
typedef boost::integral_constant< typedef boost::integral_constant<
bool, bool,
outer_traits_type::propagate_on_container_copy_assignment::value || outer_traits_type::propagate_on_container_copy_assignment::value ||
@ -635,7 +637,7 @@ class scoped_allocator_adaptor_base
, m_inner(other.inner_allocator()) , m_inner(other.inner_allocator())
{} {}
protected: public:
struct internal_type_t{}; struct internal_type_t{};
template <class OuterA2> template <class OuterA2>
@ -670,6 +672,9 @@ class scoped_allocator_adaptor_base
boost::container::swap_dispatch(this->m_inner, r.inner_allocator()); boost::container::swap_dispatch(this->m_inner, r.inner_allocator());
} }
friend void swap(scoped_allocator_adaptor_base &l, scoped_allocator_adaptor_base &r)
{ l.swap(r); }
inner_allocator_type& inner_allocator() inner_allocator_type& inner_allocator()
{ return m_inner; } { return m_inner; }
@ -682,6 +687,15 @@ class scoped_allocator_adaptor_base
const outer_allocator_type &outer_allocator() const const outer_allocator_type &outer_allocator() const
{ return static_cast<const outer_allocator_type&>(*this); } { return static_cast<const outer_allocator_type&>(*this); }
scoped_allocator_type select_on_container_copy_construction() const
{
return scoped_allocator_type
(internal_type_t()
,outer_traits_type::select_on_container_copy_construction(this->outer_allocator())
,inner_traits_type::select_on_container_copy_construction(this->inner_allocator())
);
}
private: private:
inner_allocator_type m_inner; inner_allocator_type m_inner;
}; };
@ -730,6 +744,11 @@ class scoped_allocator_adaptor_base<OuterAlloc, true
( BOOST_PP_SUB(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, n) \ ( BOOST_PP_SUB(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, n) \
, BOOST_CONTAINER_PP_IDENTITY, nat) \ , BOOST_CONTAINER_PP_IDENTITY, nat) \
> inner_allocator_type; \ > inner_allocator_type; \
typedef scoped_allocator_adaptor<OuterAlloc, BOOST_PP_ENUM_PARAMS(n, Q) \
BOOST_PP_ENUM_TRAILING \
( BOOST_PP_SUB(BOOST_CONTAINER_MAX_CONSTRUCTOR_PARAMETERS, n) \
, BOOST_CONTAINER_PP_IDENTITY, nat) \
> scoped_allocator_type; \
typedef allocator_traits<inner_allocator_type> inner_traits_type; \ typedef allocator_traits<inner_allocator_type> inner_traits_type; \
typedef boost::integral_constant< \ typedef boost::integral_constant< \
bool, \ bool, \
@ -790,7 +809,7 @@ class scoped_allocator_adaptor_base<OuterAlloc, true
, m_inner(other.inner_allocator()) \ , m_inner(other.inner_allocator()) \
{} \ {} \
\ \
protected: \ public: \
struct internal_type_t{}; \ struct internal_type_t{}; \
\ \
template <class OuterA2> \ template <class OuterA2> \
@ -824,6 +843,9 @@ class scoped_allocator_adaptor_base<OuterAlloc, true
boost::container::swap_dispatch(this->m_inner, r.inner_allocator()); \ boost::container::swap_dispatch(this->m_inner, r.inner_allocator()); \
} \ } \
\ \
friend void swap(scoped_allocator_adaptor_base &l, scoped_allocator_adaptor_base &r) \
{ l.swap(r); } \
\
inner_allocator_type& inner_allocator() \ inner_allocator_type& inner_allocator() \
{ return m_inner; } \ { return m_inner; } \
\ \
@ -836,6 +858,14 @@ class scoped_allocator_adaptor_base<OuterAlloc, true
const outer_allocator_type &outer_allocator() const \ const outer_allocator_type &outer_allocator() const \
{ return static_cast<const outer_allocator_type&>(*this); } \ { return static_cast<const outer_allocator_type&>(*this); } \
\ \
scoped_allocator_type select_on_container_copy_construction() const \
{ \
return scoped_allocator_type \
(internal_type_t() \
,outer_traits_type::select_on_container_copy_construction(this->outer_allocator()) \
,inner_traits_type::select_on_container_copy_construction(this->inner_allocator()) \
); \
} \
private: \ private: \
inner_allocator_type m_inner; \ inner_allocator_type m_inner; \
}; \ }; \
@ -874,6 +904,7 @@ class scoped_allocator_adaptor_base
typedef OuterAlloc outer_allocator_type; typedef OuterAlloc outer_allocator_type;
typedef allocator_traits<OuterAlloc> outer_traits_type; typedef allocator_traits<OuterAlloc> outer_traits_type;
typedef scoped_allocator_adaptor<OuterAlloc> inner_allocator_type; typedef scoped_allocator_adaptor<OuterAlloc> inner_allocator_type;
typedef inner_allocator_type scoped_allocator_type;
typedef allocator_traits<inner_allocator_type> inner_traits_type; typedef allocator_traits<inner_allocator_type> inner_traits_type;
typedef typename outer_traits_type:: typedef typename outer_traits_type::
propagate_on_container_copy_assignment propagate_on_container_copy_assignment; propagate_on_container_copy_assignment propagate_on_container_copy_assignment;
@ -922,7 +953,7 @@ class scoped_allocator_adaptor_base
: outer_allocator_type(other.outer_allocator()) : outer_allocator_type(other.outer_allocator())
{} {}
protected: public:
struct internal_type_t{}; struct internal_type_t{};
template <class OuterA2> template <class OuterA2>
@ -948,6 +979,9 @@ class scoped_allocator_adaptor_base
boost::container::swap_dispatch(this->outer_allocator(), r.outer_allocator()); boost::container::swap_dispatch(this->outer_allocator(), r.outer_allocator());
} }
friend void swap(scoped_allocator_adaptor_base &l, scoped_allocator_adaptor_base &r)
{ l.swap(r); }
inner_allocator_type& inner_allocator() inner_allocator_type& inner_allocator()
{ return static_cast<inner_allocator_type&>(*this); } { return static_cast<inner_allocator_type&>(*this); }
@ -959,6 +993,17 @@ class scoped_allocator_adaptor_base
const outer_allocator_type &outer_allocator() const const outer_allocator_type &outer_allocator() const
{ return static_cast<const outer_allocator_type&>(*this); } { return static_cast<const outer_allocator_type&>(*this); }
scoped_allocator_type select_on_container_copy_construction() const
{
return scoped_allocator_type
(internal_type_t()
,outer_traits_type::select_on_container_copy_construction(this->outer_allocator())
//Don't use inner_traits_type::select_on_container_copy_construction(this->inner_allocator())
//as inner_allocator() is equal to *this and that would trigger an infinite loop
, this->inner_allocator()
);
}
}; };
} //namespace container_detail { } //namespace container_detail {
@ -1164,48 +1209,37 @@ class scoped_allocator_adaptor
{} {}
scoped_allocator_adaptor &operator=(BOOST_COPY_ASSIGN_REF(scoped_allocator_adaptor) other) scoped_allocator_adaptor &operator=(BOOST_COPY_ASSIGN_REF(scoped_allocator_adaptor) other)
{ { return static_cast<scoped_allocator_adaptor&>(base_type::operator=(static_cast<const base_type &>(other))); }
base_type::operator=(static_cast<const base_type &>(other));
return *this;
}
scoped_allocator_adaptor &operator=(BOOST_RV_REF(scoped_allocator_adaptor) other) scoped_allocator_adaptor &operator=(BOOST_RV_REF(scoped_allocator_adaptor) other)
{ { return static_cast<scoped_allocator_adaptor&>(base_type::operator=(boost::move(static_cast<base_type&>(other)))); }
base_type::operator=(boost::move(static_cast<scoped_allocator_adaptor&>(other)));
return *this; #ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
} //! <b>Effects</b>: swaps *this with r.
//!
void swap(scoped_allocator_adaptor &r);
//! <b>Effects</b>: swaps *this with r. //! <b>Effects</b>: swaps *this with r.
//! //!
void swap(scoped_allocator_adaptor &r) friend void swap(scoped_allocator_adaptor &l, scoped_allocator_adaptor &r);
{
base_type::swap(r);
}
//! <b>Effects</b>: swaps *this with r.
//!
friend void swap(scoped_allocator_adaptor &l, scoped_allocator_adaptor &r)
{ l.swap(r); }
//! <b>Returns</b>: //! <b>Returns</b>:
//! `static_cast<OuterAlloc&>(*this)`. //! `static_cast<OuterAlloc&>(*this)`.
outer_allocator_type & outer_allocator() outer_allocator_type & outer_allocator();
{ return *this; }
//! <b>Returns</b>: //! <b>Returns</b>:
//! `static_cast<const OuterAlloc&>(*this)`. //! `static_cast<const OuterAlloc&>(*this)`.
const outer_allocator_type &outer_allocator() const const outer_allocator_type &outer_allocator() const;
{ return *this; }
//! <b>Returns</b>: //! <b>Returns</b>:
//! *this if `sizeof...(InnerAllocs)` is zero; otherwise, inner. //! *this if `sizeof...(InnerAllocs)` is zero; otherwise, inner.
inner_allocator_type& inner_allocator() inner_allocator_type& inner_allocator();
{ return base_type::inner_allocator(); }
//! <b>Returns</b>: //! <b>Returns</b>:
//! *this if `sizeof...(InnerAllocs)` is zero; otherwise, inner. //! *this if `sizeof...(InnerAllocs)` is zero; otherwise, inner.
inner_allocator_type const& inner_allocator() const inner_allocator_type const& inner_allocator() const;
{ return base_type::inner_allocator(); }
#endif //BOOST_CONTAINER_DOXYGEN_INVOKED
//! <b>Returns</b>: //! <b>Returns</b>:
//! `allocator_traits<OuterAlloc>::max_size(outer_allocator())`. //! `allocator_traits<OuterAlloc>::max_size(outer_allocator())`.
@ -1244,18 +1278,14 @@ class scoped_allocator_adaptor
outer_traits_type::deallocate(this->outer_allocator(), p, n); outer_traits_type::deallocate(this->outer_allocator(), p, n);
} }
#ifdef BOOST_CONTAINER_DOXYGEN_INVOKED
//! <b>Returns</b>: Allocator new scoped_allocator_adaptor object where each allocator //! <b>Returns</b>: Allocator new scoped_allocator_adaptor object where each allocator
//! A in the adaptor is initialized from the result of calling //! A in the adaptor is initialized from the result of calling
//! `allocator_traits<Allocator>::select_on_container_copy_construction()` on //! `allocator_traits<Allocator>::select_on_container_copy_construction()` on
//! the corresponding allocator in *this. //! the corresponding allocator in *this.
scoped_allocator_adaptor select_on_container_copy_construction() const scoped_allocator_adaptor select_on_container_copy_construction() const;
{ #endif //BOOST_CONTAINER_DOXYGEN_INVOKED
return scoped_allocator_adaptor
(internal_type_t()
,outer_traits_type::select_on_container_copy_construction(this->outer_allocator())
,inner_traits_type::select_on_container_copy_construction(this->inner_allocator())
);
}
/// @cond /// @cond
base_type &base() { return *this; } base_type &base() { return *this; }
@ -1426,7 +1456,8 @@ class scoped_allocator_adaptor
//template <class T1, class T2, class... Args1, class... Args2> //template <class T1, class T2, class... Args1, class... Args2>
//void construct(pair<T1, T2>* p, piecewise_construct_t, tuple<Args1...> x, tuple<Args2...> y); //void construct(pair<T1, T2>* p, piecewise_construct_t, tuple<Args1...> x, tuple<Args2...> y);
private: public:
//Internal function
template <class OuterA2> template <class OuterA2>
scoped_allocator_adaptor(internal_type_t, BOOST_FWD_REF(OuterA2) outer, const inner_allocator_type& inner) scoped_allocator_adaptor(internal_type_t, BOOST_FWD_REF(OuterA2) outer, const inner_allocator_type& inner)
: base_type(internal_type_t(), ::boost::forward<OuterA2>(outer), inner) : base_type(internal_type_t(), ::boost::forward<OuterA2>(outer), inner)

View File

@ -11,7 +11,7 @@
#ifndef BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_FWD_HPP #ifndef BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_FWD_HPP
#define BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_FWD_HPP #define BOOST_CONTAINER_ALLOCATOR_SCOPED_ALLOCATOR_FWD_HPP
#if (defined MSC_VER) && (_MSC_VER >= 1200) #if defined(_MSC_VER)
# pragma once # pragma once
#endif #endif

View File

@ -14,7 +14,7 @@
#include <boost/container/detail/config_begin.hpp> #include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp> #include <boost/container/detail/workaround.hpp>
#if (defined _MSC_VER) && (_MSC_VER >= 1200) #if defined(_MSC_VER)
# pragma once # pragma once
#endif #endif

View File

@ -361,6 +361,40 @@ namespace boost
#endif // BOOST_HAS_STDINT_H #endif // BOOST_HAS_STDINT_H
// intptr_t/uintptr_t are defined separately because they are optional and not universally available
#if defined(BOOST_WINDOWS) && !defined(_WIN32_WCE) && !defined(BOOST_HAS_STDINT_H)
// Older MSVC don't have stdint.h and have intptr_t/uintptr_t defined in stddef.h
#include <stddef.h>
#endif
// PGI seems to not support intptr_t/uintptr_t properly. BOOST_HAS_STDINT_H is not defined for this compiler by Boost.Config.
#if !defined(__PGIC__)
#if (defined(BOOST_WINDOWS) && !defined(_WIN32_WCE)) \
|| (defined(_XOPEN_UNIX) && (_XOPEN_UNIX+0 > 0) && !defined(__UCLIBC__)) \
|| defined(__CYGWIN__) \
|| defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__) \
|| defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || defined(__DragonFly__)
namespace boost {
using ::intptr_t;
using ::uintptr_t;
}
#define BOOST_HAS_INTPTR_T
// Clang pretends to be GCC, so it'll match this condition
#elif defined(__GNUC__) && defined(__INTPTR_TYPE__) && defined(__UINTPTR_TYPE__)
namespace boost {
typedef __INTPTR_TYPE__ intptr_t;
typedef __UINTPTR_TYPE__ uintptr_t;
}
#define BOOST_HAS_INTPTR_T
#endif
#endif // !defined(__PGIC__)
#endif // BOOST_CSTDINT_HPP #endif // BOOST_CSTDINT_HPP

View File

@ -7,7 +7,7 @@
* Boost Software License, Version 1.0. (See accompanying * Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland, Bart Garst * Author: Jeff Garland, Bart Garst
* $Date: 2013-06-21 08:04:12 -0700 (Fri, 21 Jun 2013) $ * $Date: 2013-10-15 08:22:02 -0700 (Tue, 15 Oct 2013) $
*/ */
@ -271,7 +271,8 @@ class format_date_parser
const_itr itr(format_str.begin()); const_itr itr(format_str.begin());
while (itr != format_str.end() && (sitr != stream_end)) { while (itr != format_str.end() && (sitr != stream_end)) {
if (*itr == '%') { if (*itr == '%') {
itr++; if ( ++itr == format_str.end())
break;
if (*itr != '%') { if (*itr != '%') {
switch(*itr) { switch(*itr) {
case 'a': case 'a':
@ -476,7 +477,8 @@ class format_date_parser
const_itr itr(format_str.begin()); const_itr itr(format_str.begin());
while (itr != format_str.end() && (sitr != stream_end)) { while (itr != format_str.end() && (sitr != stream_end)) {
if (*itr == '%') { if (*itr == '%') {
itr++; if ( ++itr == format_str.end())
break;
if (*itr != '%') { if (*itr != '%') {
switch(*itr) { switch(*itr) {
case 'b': case 'b':
@ -577,7 +579,8 @@ class format_date_parser
const_itr itr(format_str.begin()); const_itr itr(format_str.begin());
while (itr != format_str.end() && (sitr != stream_end)) { while (itr != format_str.end() && (sitr != stream_end)) {
if (*itr == '%') { if (*itr == '%') {
itr++; if ( ++itr == format_str.end())
break;
if (*itr != '%') { if (*itr != '%') {
switch(*itr) { switch(*itr) {
case 'a': case 'a':
@ -666,7 +669,8 @@ class format_date_parser
const_itr itr(format_str.begin()); const_itr itr(format_str.begin());
while (itr != format_str.end() && (sitr != stream_end)) { while (itr != format_str.end() && (sitr != stream_end)) {
if (*itr == '%') { if (*itr == '%') {
itr++; if ( ++itr == format_str.end())
break;
if (*itr != '%') { if (*itr != '%') {
//match_results mr; //match_results mr;
switch(*itr) { switch(*itr) {

View File

@ -6,7 +6,7 @@
* Boost Software License, Version 1.0. (See accompanying * Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt) * file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* Author: Jeff Garland * Author: Jeff Garland
* $Date: 2013-06-21 08:04:12 -0700 (Fri, 21 Jun 2013) $ * $Date: 2013-09-21 13:17:00 -0700 (Sat, 21 Sep 2013) $
*/ */
#include <sstream> #include <sstream>

Some files were not shown because too many files have changed in this diff Show More