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
#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/end.hpp>

View File

@ -12,7 +12,7 @@
#define BOOST_STRING_FIND_FORMAT_DETAIL_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/iterator.hpp>
#include <boost/algorithm/string/detail/find_format_store.hpp>

View File

@ -12,7 +12,7 @@
#define BOOST_STRING_FIND_FORMAT_ALL_DETAIL_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/value_type.hpp>
#include <boost/algorithm/string/detail/find_format_store.hpp>

View File

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

View File

@ -12,7 +12,7 @@
#define BOOST_STRING_FIND_ITERATOR_DETAIL_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_categories.hpp>
#include <boost/function.hpp>

View File

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

View File

@ -14,7 +14,7 @@
#include <boost/algorithm/string/config.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/end.hpp>

View File

@ -12,7 +12,7 @@
#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/end.hpp>
#include <boost/range/const_iterator.hpp>

View File

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

View File

@ -13,7 +13,7 @@
#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/end.hpp>
#include <boost/range/iterator.hpp>

View File

@ -13,7 +13,7 @@
#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/end.hpp>
#include <boost/range/iterator.hpp>

View File

@ -13,7 +13,7 @@
#include <deque>
#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/end.hpp>
#include <boost/range/const_iterator.hpp>

View File

@ -15,7 +15,7 @@
#include <boost/iterator/iterator_facade.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/end.hpp>
#include <boost/range/iterator.hpp>
@ -132,12 +132,7 @@ namespace boost {
// increment
void increment()
{
if(m_Match.begin() == m_Match.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

View File

@ -13,7 +13,7 @@
#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/end.hpp>
#include <boost/range/iterator.hpp>

View File

@ -13,7 +13,7 @@
#include <boost/detail/iterator.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/algorithm/string/detail/formatter.hpp>

View File

@ -16,7 +16,7 @@
#include <iterator>
#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/end.hpp>
#include <boost/range/iterator.hpp>

View File

@ -17,7 +17,7 @@
#include <boost/range/iterator.hpp>
#include <boost/range/const_iterator.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/find.hpp>

View File

@ -14,7 +14,7 @@
#include <boost/algorithm/string/config.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/end.hpp>
#include <boost/range/iterator.hpp>

View File

@ -13,7 +13,7 @@
#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/end.hpp>
#include <boost/range/iterator.hpp>

View File

@ -17,7 +17,7 @@
#include <boost/range/end.hpp>
#include <boost/range/const_iterator.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/classification.hpp>

View File

@ -34,6 +34,7 @@
#elif defined(BOOST_ENABLE_ASSERT_HANDLER)
#include <boost/config.hpp>
#include <boost/current_function.hpp>
namespace boost
@ -42,7 +43,7 @@ namespace boost
char const * function, char const * file, long line); // user defined
} // namespace boost
#define BOOST_ASSERT(expr) ((expr) \
#define BOOST_ASSERT(expr) (BOOST_LIKELY(!!(expr)) \
? ((void)0) \
: ::boost::assertion_failed(#expr, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__))
@ -63,6 +64,7 @@ namespace boost
#elif defined(BOOST_ENABLE_ASSERT_HANDLER)
#include <boost/config.hpp>
#include <boost/current_function.hpp>
namespace boost
@ -71,7 +73,7 @@ namespace boost
char const * function, char const * file, long line); // user defined
} // namespace boost
#define BOOST_ASSERT_MSG(expr, msg) ((expr) \
#define BOOST_ASSERT_MSG(expr, msg) (BOOST_LIKELY(!!(expr)) \
? ((void)0) \
: ::boost::assertion_failed_msg(#expr, msg, BOOST_CURRENT_FUNCTION, __FILE__, __LINE__))
@ -80,6 +82,7 @@ namespace boost
#define BOOST_ASSERT_HPP
#include <cstdlib>
#include <iostream>
#include <boost/config.hpp>
#include <boost/current_function.hpp>
// IDE's like Visual Studio perform better if output goes to std::cout or
@ -94,26 +97,28 @@ namespace boost
{
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)
{
BOOST_ASSERT_MSG_OSTREAM
<< "***** Internal Program Error - assertion (" << expr << ") failed in "
<< function << ":\n"
<< file << '(' << line << "): " << msg << std::endl;
#ifdef UNDER_CE
#ifdef UNDER_CE
// The Windows CE CRT library does not have abort() so use exit(-1) instead.
std::exit(-1);
#else
#else
std::abort();
#endif
#endif
}
} // detail
} // assertion
} // detail
#endif
#define BOOST_ASSERT_MSG(expr, msg) ((expr) \
#define BOOST_ASSERT_MSG(expr, msg) (BOOST_LIKELY(!!(expr)) \
? ((void)0) \
: ::boost::assertion::detail::assertion_failed_msg(#expr, msg, \
BOOST_CURRENT_FUNCTION, __FILE__, __LINE__))

View File

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

View File

@ -22,7 +22,7 @@
#include <boost/mpl/and.hpp>
#endif
#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
@ -60,6 +60,10 @@ namespace boost {
#define BOOST_ATOMIC_LLONG_LOCK_FREE 0
#endif
#ifndef BOOST_ATOMIC_INT128_LOCK_FREE
#define BOOST_ATOMIC_INT128_LOCK_FREE 0
#endif
#ifndef BOOST_ATOMIC_POINTER_LOCK_FREE
#define BOOST_ATOMIC_POINTER_LOCK_FREE 0
#endif
@ -112,11 +116,18 @@ private:
mpl::and_< boost::is_integral<T>, boost::is_signed<T> >::value
#endif
> super;
public:
atomic(void) BOOST_NOEXCEPT : super() {}
BOOST_CONSTEXPR atomic(value_type v) BOOST_NOEXCEPT : super(v) {}
typedef typename super::value_arg_type value_arg_type;
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);
return v;
@ -127,14 +138,8 @@ public:
return this->load();
}
#ifdef BOOST_NO_CXX11_DELETED_FUNCTIONS
private:
atomic(const atomic &) /* =delete */ ;
atomic & operator=(const atomic &) volatile /* =delete */ ;
#else
atomic(const atomic &) = delete;
atomic & operator=(const atomic &) volatile = delete;
#endif
BOOST_DELETED_FUNCTION(atomic(atomic const&))
BOOST_DELETED_FUNCTION(atomic& operator=(atomic const&) volatile)
};
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::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(__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__)
#if defined(BOOST_HAS_INTPTR_T)
typedef atomic<intptr_t> atomic_intptr_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
#ifndef BOOST_ATOMIC_FLAG_LOCK_FREE
@ -229,9 +218,11 @@ public:
{
v_.store(false, order);
}
BOOST_DELETED_FUNCTION(atomic_flag(atomic_flag const&))
BOOST_DELETED_FUNCTION(atomic_flag& operator=(atomic_flag const&))
private:
atomic_flag(const atomic_flag &) /* = delete */ ;
atomic_flag & operator=(const atomic_flag &) /* = delete */ ;
atomic<bool> v_;
};
#endif

View File

@ -19,7 +19,7 @@
#include <boost/atomic/detail/config.hpp>
#include <boost/atomic/detail/lockpool.hpp>
#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
@ -155,7 +155,8 @@ namespace detail {
inline memory_order
calculate_failure_order(memory_order order)
{
switch(order) {
switch(order)
{
case memory_order_acq_rel:
return memory_order_acquire;
case memory_order_release:
@ -172,11 +173,12 @@ private:
typedef base_atomic this_type;
typedef T value_type;
typedef lockpool::scoped_lock guard_type;
typedef char storage_type[sizeof(value_type)];
protected:
typedef value_type const& value_arg_type;
public:
base_atomic(void) {}
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
BOOST_CONSTEXPR explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(v)
{}
@ -249,15 +251,16 @@ public:
}
BOOST_ATOMIC_DECLARE_BASE_OPERATORS
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private:
char * storage_ptr() volatile const BOOST_NOEXCEPT
{
return const_cast<char *>(&reinterpret_cast<char const volatile &>(v_));
}
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
T v_;
};
@ -269,9 +272,13 @@ private:
typedef T value_type;
typedef T difference_type;
typedef lockpool::scoped_lock guard_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) {}
base_atomic(void) {}
void
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_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
value_type v_;
};
@ -393,11 +402,15 @@ class base_atomic<T *, void *, Size, Sign>
private:
typedef base_atomic this_type;
typedef T * value_type;
typedef ptrdiff_t difference_type;
typedef std::ptrdiff_t difference_type;
typedef lockpool::scoped_lock guard_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) {}
base_atomic(void) {}
void
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_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
value_type v_;
};
@ -485,12 +500,16 @@ class base_atomic<void *, void *, Size, Sign>
{
private:
typedef base_atomic this_type;
typedef ptrdiff_t difference_type;
typedef std::ptrdiff_t difference_type;
typedef void * value_type;
typedef lockpool::scoped_lock guard_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) {}
base_atomic(void) {}
void
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_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
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
// a platform_cmpxchg32_strong primitive.
#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_ATOMIC_HAS_PRAGMA_ONCE
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
@ -31,13 +32,18 @@ namespace detail {
template<typename T, bool Sign>
class base_atomic<T, int, 1, Sign>
{
private:
typedef base_atomic this_type;
typedef T value_type;
typedef T difference_type;
typedef uint32_t storage_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) {}
base_atomic(void) {}
void
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_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
storage_type v_;
};
template<typename T, bool Sign>
class base_atomic<T, int, 2, Sign>
{
private:
typedef base_atomic this_type;
typedef T value_type;
typedef T difference_type;
typedef uint32_t storage_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) {}
base_atomic(void) {}
void
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_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
storage_type v_;
};
template<typename T, bool Sign>
class base_atomic<T, int, 4, 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) {}
base_atomic(void) {}
void
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_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
value_type v_;
};
@ -412,12 +434,17 @@ private:
template<bool Sign>
class base_atomic<void *, void *, 4, Sign>
{
private:
typedef base_atomic this_type;
typedef void * value_type;
typedef ptrdiff_t difference_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) {}
base_atomic(void) {}
void
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_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
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 *, 4, Sign>
{
private:
typedef base_atomic this_type;
typedef T * value_type;
typedef ptrdiff_t difference_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) {}
base_atomic(void) {}
void
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_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
value_type v_;
};
@ -606,17 +642,21 @@ private:
template<typename T, bool Sign>
class base_atomic<T, void, 1, Sign>
{
private:
typedef base_atomic this_type;
typedef T value_type;
typedef uint32_t 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));
}
base_atomic(void) {}
void
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_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
storage_type v_;
};
template<typename T, bool Sign>
class base_atomic<T, void, 2, Sign>
{
private:
typedef base_atomic this_type;
typedef T value_type;
typedef uint32_t 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));
}
base_atomic(void) {}
void
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_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
storage_type v_;
};
template<typename T, bool Sign>
class base_atomic<T, void, 4, Sign>
{
private:
typedef base_atomic this_type;
typedef T value_type;
typedef uint32_t 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));
}
base_atomic(void) {}
void
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_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
storage_type v_;
};

View File

@ -9,13 +9,14 @@
// Copyright (c) 2013 Tim Blechmann
#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_ATOMIC_HAS_PRAGMA_ONCE
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
@ -28,13 +29,18 @@ namespace detail {
template<typename T, bool Sign>
class base_atomic<T, int, 1, Sign>
{
private:
typedef base_atomic this_type;
typedef T value_type;
typedef T difference_type;
typedef uint32_t storage_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) {}
base_atomic(void) {}
void
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 failure_order) volatile BOOST_NOEXCEPT
{
for(;;) {
while (true)
{
value_type tmp = expected;
if (compare_exchange_weak(tmp, desired, success_order, failure_order))
return true;
if (tmp != expected) {
if (tmp != expected)
{
expected = tmp;
return false;
}
@ -155,22 +163,29 @@ public:
}
BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
storage_type v_;
};
template<typename T, bool Sign>
class base_atomic<T, int, 2, Sign>
{
private:
typedef base_atomic this_type;
typedef T value_type;
typedef T difference_type;
typedef uint32_t storage_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) {}
base_atomic(void) {}
void
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 failure_order) volatile BOOST_NOEXCEPT
{
for(;;) {
while (true)
{
value_type tmp = expected;
if (compare_exchange_weak(tmp, desired, success_order, failure_order))
return true;
if (tmp != expected) {
if (tmp != expected)
{
expected = tmp;
return false;
}
@ -291,21 +308,28 @@ public:
}
BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
storage_type v_;
};
template<typename T, bool Sign>
class base_atomic<T, int, 4, 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) {}
base_atomic(void) {}
void
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 failure_order) volatile BOOST_NOEXCEPT
{
for(;;) {
while (true)
{
value_type tmp = expected;
if (compare_exchange_weak(tmp, desired, success_order, failure_order))
return true;
if (tmp != expected) {
if (tmp != expected)
{
expected = tmp;
return false;
}
@ -422,9 +448,11 @@ public:
}
BOOST_ATOMIC_DECLARE_INTEGRAL_OPERATORS
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
value_type v_;
};
@ -433,12 +461,17 @@ private:
template<bool Sign>
class base_atomic<void *, void *, 4, Sign>
{
private:
typedef base_atomic this_type;
typedef void * value_type;
typedef ptrdiff_t difference_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) {}
base_atomic(void) {}
void
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 failure_order) volatile BOOST_NOEXCEPT
{
for(;;) {
while (true)
{
value_type tmp = expected;
if (compare_exchange_weak(tmp, desired, success_order, failure_order))
return true;
if (tmp != expected) {
if (tmp != expected)
{
expected = tmp;
return false;
}
@ -528,21 +563,28 @@ public:
}
BOOST_ATOMIC_DECLARE_VOID_POINTER_OPERATORS
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
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 *, 4, Sign>
{
private:
typedef base_atomic this_type;
typedef T * value_type;
typedef ptrdiff_t difference_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) {}
base_atomic(void) {}
void
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 failure_order) volatile BOOST_NOEXCEPT
{
for(;;) {
while (true)
{
value_type tmp = expected;
if (compare_exchange_weak(tmp, desired, success_order, failure_order))
return true;
if (tmp != expected) {
if (tmp != expected)
{
expected = tmp;
return false;
}
@ -632,9 +676,11 @@ public:
}
BOOST_ATOMIC_DECLARE_POINTER_OPERATORS
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
value_type v_;
};
@ -643,17 +689,21 @@ private:
template<typename T, bool Sign>
class base_atomic<T, void, 1, Sign>
{
private:
typedef base_atomic this_type;
typedef T value_type;
typedef uint32_t 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));
}
base_atomic(void) {}
void
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 failure_order) volatile BOOST_NOEXCEPT
{
for(;;) {
while (true)
{
value_type tmp = expected;
if (compare_exchange_weak(tmp, desired, success_order, failure_order))
return true;
if (tmp != expected) {
if (tmp != expected)
{
expected = tmp;
return false;
}
@ -734,26 +786,32 @@ public:
}
BOOST_ATOMIC_DECLARE_BASE_OPERATORS
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
storage_type v_;
};
template<typename T, bool Sign>
class base_atomic<T, void, 2, Sign>
{
private:
typedef base_atomic this_type;
typedef T value_type;
typedef uint32_t 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));
}
base_atomic(void) {}
void
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 failure_order) volatile BOOST_NOEXCEPT
{
for(;;) {
while (true)
{
value_type tmp = expected;
if (compare_exchange_weak(tmp, desired, success_order, failure_order))
return true;
if (tmp != expected) {
if (tmp != expected)
{
expected = tmp;
return false;
}
@ -834,26 +894,32 @@ public:
}
BOOST_ATOMIC_DECLARE_BASE_OPERATORS
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
storage_type v_;
};
template<typename T, bool Sign>
class base_atomic<T, void, 4, Sign>
{
private:
typedef base_atomic this_type;
typedef T value_type;
typedef uint32_t 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));
}
base_atomic(void) {}
void
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 failure_order) volatile BOOST_NOEXCEPT
{
for(;;) {
while (true)
{
value_type tmp = expected;
if (compare_exchange_weak(tmp, desired, success_order, failure_order))
return true;
if (tmp != expected) {
if (tmp != expected)
{
expected = tmp;
return false;
}
@ -934,9 +1002,11 @@ public:
}
BOOST_ATOMIC_DECLARE_BASE_OPERATORS
BOOST_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
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) 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
// 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 <boost/cstdint.hpp>
#include <boost/memory_order.hpp>
#include <boost/atomic/detail/config.hpp>
#include <boost/atomic/detail/base.hpp>
#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
@ -31,12 +32,17 @@ namespace detail {
template<typename T, bool Sign>
class base_atomic<T, int, 8, 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) {}
base_atomic(void) {}
void
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_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
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_;
};
@ -350,15 +164,20 @@ private:
template<typename T, bool Sign>
class base_atomic<T, void, 8, Sign>
{
private:
typedef base_atomic this_type;
typedef T value_type;
typedef uint64_t 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));
}
base_atomic(void) {}
void
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_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
storage_type v_;
};

View File

@ -9,46 +9,8 @@
#include <boost/config.hpp>
#if (defined(_MSC_VER) && (_MSC_VER >= 1020)) || defined(__GNUC__) || defined(BOOST_CLANG) || defined(BOOST_INTEL) || defined(__COMO__) || defined(__DMC__)
#define BOOST_ATOMIC_HAS_PRAGMA_ONCE
#endif
#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE
#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

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

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -8,11 +8,12 @@
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <string.h>
#include <cstddef>
#include <boost/cstdint.hpp>
#include <boost/atomic/detail/config.hpp>
#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
@ -65,7 +66,8 @@ namespace detail {
inline void
ppc_fence_before(memory_order order)
{
switch(order) {
switch(order)
{
case memory_order_release:
case memory_order_acq_rel:
#if defined(__powerpc64__)
@ -81,7 +83,8 @@ ppc_fence_before(memory_order order)
inline void
ppc_fence_after(memory_order order)
{
switch(order) {
switch(order)
{
case memory_order_acquire:
case memory_order_acq_rel:
case memory_order_seq_cst:
@ -95,7 +98,8 @@ ppc_fence_after(memory_order order)
inline void
ppc_fence_after_store(memory_order order)
{
switch(order) {
switch(order)
{
case memory_order_seq_cst:
__asm__ __volatile__ ("sync");
default:;
@ -199,13 +203,18 @@ namespace detail {
template<typename T>
class base_atomic<T, int, 1, true>
{
private:
typedef base_atomic this_type;
typedef T value_type;
typedef int32_t storage_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) {}
base_atomic(void) {}
void
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_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
storage_type v_;
};
template<typename T>
class base_atomic<T, int, 1, false>
{
private:
typedef base_atomic this_type;
typedef T value_type;
typedef uint32_t storage_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) {}
base_atomic(void) {}
void
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_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
storage_type v_;
};
template<typename T>
class base_atomic<T, int, 2, true>
{
private:
typedef base_atomic this_type;
typedef T value_type;
typedef int32_t storage_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) {}
base_atomic(void) {}
void
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_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
storage_type v_;
};
template<typename T>
class base_atomic<T, int, 2, false>
{
private:
typedef base_atomic this_type;
typedef T value_type;
typedef uint32_t storage_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) {}
base_atomic(void) {}
void
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_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
storage_type v_;
};
template<typename T, bool Sign>
class base_atomic<T, int, 4, 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) {}
base_atomic(void) {}
void
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_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
value_type v_;
};
@ -1303,12 +1342,17 @@ private:
template<typename T, bool Sign>
class base_atomic<T, int, 8, 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) {}
base_atomic(void) {}
void
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_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
value_type v_;
};
@ -1524,12 +1570,17 @@ private:
template<bool Sign>
class base_atomic<void *, void *, 4, Sign>
{
private:
typedef base_atomic this_type;
typedef ptrdiff_t difference_type;
typedef std::ptrdiff_t difference_type;
typedef void * value_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) {}
base_atomic(void) {}
void
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_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
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 *, 4, Sign>
{
private:
typedef base_atomic this_type;
typedef T * value_type;
typedef ptrdiff_t difference_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) {}
base_atomic(void) {}
void
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_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
value_type v_;
};
@ -1860,12 +1920,17 @@ private:
template<bool Sign>
class base_atomic<void *, void *, 8, Sign>
{
private:
typedef base_atomic this_type;
typedef ptrdiff_t difference_type;
typedef std::ptrdiff_t difference_type;
typedef void * value_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) {}
base_atomic(void) {}
void
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_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
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>
{
private:
typedef base_atomic this_type;
typedef T * value_type;
typedef ptrdiff_t difference_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) {}
base_atomic(void) {}
void
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_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
value_type v_;
};
@ -2198,15 +2272,20 @@ private:
template<typename T, bool Sign>
class base_atomic<T, void, 1, Sign>
{
private:
typedef base_atomic this_type;
typedef T value_type;
typedef uint32_t 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));
}
base_atomic(void) {}
void
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_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
storage_type v_;
};
template<typename T, bool Sign>
class base_atomic<T, void, 2, Sign>
{
private:
typedef base_atomic this_type;
typedef T value_type;
typedef uint32_t 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));
}
base_atomic(void) {}
void
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_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
storage_type v_;
};
template<typename T, bool Sign>
class base_atomic<T, void, 4, Sign>
{
private:
typedef base_atomic this_type;
typedef T value_type;
typedef uint32_t 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));
}
base_atomic(void) {}
void
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_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
storage_type v_;
};
@ -2655,17 +2748,21 @@ private:
template<typename T, bool Sign>
class base_atomic<T, void, 8, Sign>
{
private:
typedef base_atomic this_type;
typedef T value_type;
typedef uint64_t 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));
}
base_atomic(void) {}
void
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_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
storage_type v_;
};
#endif
}
@ -2812,7 +2912,8 @@ private:
inline void
atomic_thread_fence(memory_order order)
{
switch(order) {
switch(order)
{
case memory_order_acquire:
__asm__ __volatile__ ("isync" ::: "memory");
break;
@ -2832,7 +2933,8 @@ atomic_thread_fence(memory_order order)
inline void
atomic_signal_fence(memory_order order)
{
switch(order) {
switch(order)
{
case memory_order_acquire:
case memory_order_release:
case memory_order_acq_rel:

View File

@ -8,11 +8,12 @@
// See accompanying file LICENSE_1_0.txt or copy at
// http://www.boost.org/LICENSE_1_0.txt)
#include <string.h>
#include <cstddef>
#include <boost/cstdint.hpp>
#include <boost/atomic/detail/config.hpp>
#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
@ -23,7 +24,8 @@ namespace detail {
inline void
platform_fence_before(memory_order order)
{
switch(order) {
switch(order)
{
case memory_order_relaxed:
case memory_order_acquire:
case memory_order_consume:
@ -43,7 +45,8 @@ platform_fence_before(memory_order order)
inline void
platform_fence_after(memory_order order)
{
switch(order) {
switch(order)
{
case memory_order_relaxed:
case memory_order_release:
break;
@ -66,7 +69,8 @@ platform_fence_after(memory_order order)
inline void
platform_fence_after_store(memory_order order)
{
switch(order) {
switch(order)
{
case memory_order_seq_cst:
__asm__ __volatile__ ("membar #Sync" ::: "memory");
default:;
@ -141,7 +145,8 @@ namespace boost {
inline void
atomic_thread_fence(memory_order order)
{
switch(order) {
switch(order)
{
case memory_order_relaxed:
break;
case memory_order_release:
@ -177,13 +182,18 @@ namespace detail {
template<typename T>
class base_atomic<T, int, 1, true>
{
private:
typedef base_atomic this_type;
typedef T value_type;
typedef T difference_type;
typedef int32_t storage_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) {}
base_atomic(void) {}
void
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_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
storage_type v_;
};
template<typename T>
class base_atomic<T, int, 1, false>
{
private:
typedef base_atomic this_type;
typedef T value_type;
typedef T difference_type;
typedef uint32_t storage_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) {}
base_atomic(void) {}
void
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_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
storage_type v_;
};
template<typename T>
class base_atomic<T, int, 2, true>
{
private:
typedef base_atomic this_type;
typedef T value_type;
typedef T difference_type;
typedef int32_t storage_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) {}
base_atomic(void) {}
void
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_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
storage_type v_;
};
template<typename T>
class base_atomic<T, int, 2, false>
{
private:
typedef base_atomic this_type;
typedef T value_type;
typedef T difference_type;
typedef uint32_t storage_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) {}
base_atomic(void) {}
void
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_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
storage_type v_;
};
template<typename T, bool Sign>
class base_atomic<T, int, 4, 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) {}
base_atomic(void) {}
void
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_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
value_type v_;
};
@ -791,12 +831,17 @@ private:
template<bool Sign>
class base_atomic<void *, void *, 4, Sign>
{
private:
typedef base_atomic this_type;
typedef ptrdiff_t difference_type;
typedef std::ptrdiff_t difference_type;
typedef void * value_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) {}
base_atomic(void) {}
void
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_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
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 *, 4, Sign>
{
private:
typedef base_atomic this_type;
typedef T * value_type;
typedef ptrdiff_t difference_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) {}
base_atomic(void) {}
void
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_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
value_type v_;
};
@ -983,15 +1036,20 @@ private:
template<typename T, bool Sign>
class base_atomic<T, void, 1, Sign>
{
private:
typedef base_atomic this_type;
typedef T value_type;
typedef uint32_t storage_type;
protected:
typedef value_type const& value_arg_type;
public:
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
BOOST_CONSTEXPR explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0)
{
memcpy(&v_, &v, sizeof(value_type));
}
base_atomic(void) {}
void
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_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
storage_type v_;
};
template<typename T, bool Sign>
class base_atomic<T, void, 2, Sign>
{
private:
typedef base_atomic this_type;
typedef T value_type;
typedef uint32_t storage_type;
protected:
typedef value_type const& value_arg_type;
public:
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
BOOST_CONSTEXPR explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0)
{
memcpy(&v_, &v, sizeof(value_type));
}
base_atomic(void) {}
void
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_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
storage_type v_;
};
template<typename T, bool Sign>
class base_atomic<T, void, 4, Sign>
{
private:
typedef base_atomic this_type;
typedef T value_type;
typedef uint32_t storage_type;
protected:
typedef value_type const& value_arg_type;
public:
BOOST_DEFAULTED_FUNCTION(base_atomic(void), {})
BOOST_CONSTEXPR explicit base_atomic(value_type const& v) BOOST_NOEXCEPT : v_(0)
{
memcpy(&v_, &v, sizeof(value_type));
}
base_atomic(void) {}
void
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_DELETED_FUNCTION(base_atomic(base_atomic const&))
BOOST_DELETED_FUNCTION(base_atomic& operator=(base_atomic const&))
private:
base_atomic(const base_atomic &) /* = delete */ ;
void operator=(const base_atomic &) /* = delete */ ;
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/builder.hpp>
#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif

View File

@ -10,7 +10,7 @@
#include <boost/atomic/detail/config.hpp>
#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
@ -43,6 +43,11 @@
#define BOOST_ATOMIC_INTERLOCKED_OR(dest, arg) _InterlockedOr((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
// MSVC 2010 and later provide intrinsics for 8 and 16 bit integers.
@ -81,14 +86,12 @@
#if defined(_M_AMD64) || defined(_M_IA64)
#pragma intrinsic(_InterlockedCompareExchange64)
#pragma intrinsic(_InterlockedExchangeAdd64)
#pragma intrinsic(_InterlockedExchange64)
#pragma intrinsic(_InterlockedAnd64)
#pragma intrinsic(_InterlockedOr64)
#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_EXCHANGE64(dest, newval) _InterlockedExchange64((__int64*)(dest), (__int64)(newval))
#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/atomic/detail/config.hpp>
#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
@ -163,6 +163,7 @@ public:
return expected;
}
};
#define BOOST_ATOMIC_FLAG_LOCK_FREE 2
}

View File

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

View File

@ -11,11 +11,17 @@
#include <boost/atomic/detail/config.hpp>
#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#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>
@ -32,7 +38,10 @@
// I don't know how complete it is.
#elif defined(__GNUC__) && (defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \
|| 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>

View File

@ -10,7 +10,7 @@
#include <boost/atomic/detail/config.hpp>
#include <boost/type_traits/is_integral.hpp>
#ifdef BOOST_ATOMIC_HAS_PRAGMA_ONCE
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
@ -36,7 +36,7 @@ struct storage_size_of
enum _
{
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
#define BOOST_CHRONO_DETAIL_INLINED_WIN_CHRONO_HPP
#include <boost/detail/win/time.hpp>
#include <boost/detail/win/timers.hpp>
#include <boost/detail/win/GetLastError.hpp>
#include <boost/detail/winapi/time.hpp>
#include <boost/detail/winapi/timers.hpp>
#include <boost/detail/winapi/GetLastError.hpp>
namespace boost
{
@ -25,8 +25,8 @@ namespace chrono_detail
BOOST_CHRONO_INLINE double get_nanosecs_per_tic() BOOST_NOEXCEPT
{
boost::detail::win32::LARGE_INTEGER_ freq;
if ( !boost::detail::win32::QueryPerformanceFrequency( &freq ) )
boost::detail::winapi::LARGE_INTEGER_ freq;
if ( !boost::detail::winapi::QueryPerformanceFrequency( &freq ) )
return 0.0L;
return double(1000000000.0L / freq.QuadPart);
}
@ -37,9 +37,9 @@ namespace chrono_detail
{
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) ||
(!boost::detail::win32::QueryPerformanceCounter( &pcount )) )
(!boost::detail::winapi::QueryPerformanceCounter( &pcount )) )
{
BOOST_ASSERT(0 && "Boost::Chrono - Internal Error");
return steady_clock::time_point();
@ -55,14 +55,14 @@ namespace chrono_detail
{
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)
|| (!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)
? ERROR_NOT_SUPPORTED
: boost::detail::win32::GetLastError());
: boost::detail::winapi::GetLastError());
if (BOOST_CHRONO_IS_THROWS(ec)) {
boost::throw_exception(
system::system_error(
@ -89,15 +89,8 @@ namespace chrono_detail
BOOST_CHRONO_INLINE
system_clock::time_point system_clock::now() BOOST_NOEXCEPT
{
boost::detail::win32::FILETIME_ ft;
#if defined(UNDER_CE)
// 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
boost::detail::winapi::FILETIME_ ft;
boost::detail::winapi::GetSystemTimeAsFileTime( &ft ); // never fails
return system_clock::time_point(
system_clock::duration(
((static_cast<__int64>( ft.dwHighDateTime ) << 32) | ft.dwLowDateTime)
@ -110,21 +103,17 @@ namespace chrono_detail
BOOST_CHRONO_INLINE
system_clock::time_point system_clock::now( system::error_code & ec )
{
boost::detail::win32::FILETIME_ ft;
#if defined(UNDER_CE)
// 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
boost::detail::winapi::FILETIME_ ft;
boost::detail::winapi::GetSystemTimeAsFileTime( &ft ); // never fails
if (!BOOST_CHRONO_IS_THROWS(ec))
{
ec.clear();
}
return time_point(duration(
(static_cast<__int64>( ft.dwHighDateTime ) << 32) | ft.dwLowDateTime));
return system_clock::time_point(
system_clock::duration(
((static_cast<__int64>( ft.dwHighDateTime ) << 32) | ft.dwLowDateTime)
-116444736000000000LL
));
}
#endif
@ -132,7 +121,6 @@ namespace chrono_detail
std::time_t system_clock::to_time_t(const system_clock::time_point& t) BOOST_NOEXCEPT
{
__int64 temp = t.time_since_epoch().count();
temp /= 10000000;
return static_cast<std::time_t>( temp );
}
@ -142,7 +130,6 @@ namespace chrono_detail
{
__int64 temp = t;
temp *= 10000000;
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/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 <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 cb_details {
@ -28,9 +38,11 @@ template<class ForwardIterator, class Diff, class T, class Alloc>
void uninitialized_fill_n_with_alloc(
ForwardIterator first, Diff n, const T& item, Alloc& alloc);
template<class InputIterator, class ForwardIterator, class Alloc>
ForwardIterator uninitialized_copy_with_alloc(
InputIterator first, InputIterator last, ForwardIterator dest, Alloc& alloc);
template<class ValueType, class InputIterator, class ForwardIterator>
ForwardIterator uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator dest);
template<class ValueType, class InputIterator, class ForwardIterator>
ForwardIterator uninitialized_move_if_noexcept(InputIterator first, InputIterator last, ForwardIterator dest);
/*!
\struct const_traits
@ -115,21 +127,25 @@ private:
\struct assign_range
\brief Helper functor for assigning range of items.
*/
template <class Iterator, class Alloc>
template <class ValueType, class Iterator>
struct assign_range {
const Iterator& m_first;
const Iterator& m_last;
Alloc& m_alloc;
assign_range(const Iterator& first, const Iterator& last, Alloc& alloc)
: m_first(first), m_last(last), m_alloc(alloc) {}
Iterator m_first;
Iterator m_last;
assign_range(const Iterator& first, const Iterator& last) BOOST_NOEXCEPT
: m_first(first), m_last(last) {}
template <class Pointer>
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
\brief Capacity controller of the space optimized circular buffer.
@ -137,18 +153,19 @@ private:
template <class Size>
class capacity_control {
//! The capacity of the space optimized circular buffer.
//! The capacity of the space-optimized circular buffer.
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;
public:
//! Constructor.
capacity_control(Size buffer_capacity, Size min_buffer_capacity = 0)
: 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
: m_capacity(buffer_capacity), m_min_capacity(min_buffer_capacity)
{ // Check for capacity lower than min_capacity.
BOOST_CB_ASSERT(buffer_capacity >= min_buffer_capacity);
}
// 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)
/*!
\fn ForwardIterator uninitialized_copy_with_alloc(InputIterator first, InputIterator last, ForwardIterator dest,
Alloc& alloc)
\brief Equivalent of <code>std::uninitialized_copy</code> with allocator.
\fn ForwardIterator uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator dest)
\brief Equivalent of <code>std::uninitialized_copy</code> but with explicit specification of value type.
*/
template<class InputIterator, class ForwardIterator, class Alloc>
inline ForwardIterator uninitialized_copy_with_alloc(InputIterator first, InputIterator last, ForwardIterator dest,
Alloc& alloc) {
template<class ValueType, class InputIterator, class ForwardIterator>
inline ForwardIterator uninitialized_copy(InputIterator first, InputIterator last, ForwardIterator dest) {
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;
BOOST_TRY {
for (; first != last; ++first, ++dest)
alloc.construct(dest, *first);
::new (dest) value_type(*first);
} BOOST_CATCH(...) {
for (; next != dest; ++next)
alloc.destroy(next);
next->~value_type();
BOOST_RETHROW
}
BOOST_CATCH_END
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)
\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
#if defined(_MSC_VER)
# pragma warning(pop)
#endif
#endif // #if !defined(BOOST_CIRCULAR_BUFFER_DETAILS_HPP)

View File

@ -1,6 +1,8 @@
// Implementation of the circular buffer adaptor.
// 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
// 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
\brief Space optimized circular buffer container adaptor.
For detailed documentation of the space_optimized_circular_buffer visit:
http://www.boost.org/libs/circular_buffer/doc/space_optimized.html
<code>T</code> must be a copyable class or must have an noexcept move constructor
and move assignment operator.
*/
template <class T, class Alloc>
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>::const_array_range const_array_range;
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.
/*!
<p><pre>
class capacity_control {
size_type m_capacity;
size_type m_min_capacity;
public:
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; }
size_type min_capacity() const { return m_min_capacity; }
operator size_type() const { return m_capacity; }
};</pre></p>
\pre <code>capacity >= min_capacity</code>
<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>
/* <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
and this would expose all the functions in details.
There must be a better way of doing this.
*/
/*! Capacity controller of the space optimized circular buffer.
\see capacity_control in details.hpp.
<p>
<code>
class capacity_control<br>
{<br>
size_type m_capacity; // Available capacity.<br>
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
<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>%size_type()</code> provides implicit conversion to the <code>size_type</code> which allows to treat the
<code>circular_buffer_space_optimized</code> with other STL containers.
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
<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;
@ -98,7 +123,7 @@ public:
#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
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
using circular_buffer<T, Alloc>::operator[];
#endif
@ -125,7 +150,7 @@ public:
Constant (in the size of the <code>circular_buffer_space_optimized</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
<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>).
\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>.
/*!
@ -155,7 +180,7 @@ public:
\sa <code>reserve()</code>, <code>size()</code>, <code>max_size()</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)
@ -164,7 +189,7 @@ public:
\note This method is not intended to be used directly by the user.
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)
@ -178,9 +203,9 @@ public:
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>.
\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).
\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
Strong.
\par Iterator Invalidation
@ -222,7 +247,7 @@ public:
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
used).
\throws Whatever <code>T::T(const T&)</code> throws.
Whatever <code>T::T(const T&)</code> throws.
\par Exception Safety
Basic.
\par Iterator Invalidation
@ -257,7 +282,7 @@ public:
\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
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
Strong.
\par Iterator Invalidation
@ -293,7 +318,7 @@ public:
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
used).
\throws Whatever <code>T::T(const T&)</code> throws.
Whatever <code>T::T(const T&)</code> throws.
\par Exception Safety
Basic.
\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
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)
, m_capacity_ctrl(0) {}
@ -382,7 +407,7 @@ public:
\param alloc The allocator.
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
used).
\throws Whatever <code>T::T(const T&)</code> throws.
Whatever <code>T::T(const T&)</code> throws.
\par Complexity
Linear (in the <code>n</code>).
*/
@ -424,7 +449,7 @@ public:
\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
used).
\throws Whatever <code>T::T(const T&)</code> throws.
Whatever <code>T::T(const T&)</code> throws.
\par Complexity
Linear (in the size of <code>cb</code>).
*/
@ -432,6 +457,23 @@ public:
: circular_buffer<T, Alloc>(cb.begin(), cb.end(), cb.get_allocator())
, 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.
/*!
\pre Valid range <code>[first, last)</code>.<br>
@ -446,7 +488,8 @@ public:
\param alloc The allocator.
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
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
Linear (in the <code>std::distance(first, last)</code>).
*/
@ -477,7 +520,7 @@ public:
\param alloc The allocator.
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
used).
\throws Whatever <code>T::T(const T&)</code> throws.
Whatever <code>T::T(const T&)</code> throws.
\par Complexity
Linear (in <code>std::distance(first, last)</code>; in
<code>min[capacity_ctrl.%capacity(), std::distance(first, last)]</code> if the <code>InputIterator</code>
@ -552,6 +595,24 @@ public:
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.
/*!
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.
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
used).
\throws Whatever <code>T::T(const T&)</code> throws.
Whatever <code>T::T(const T&)</code> throws.
\par Exception Safety
Basic.
\par Iterator Invalidation
@ -596,7 +657,7 @@ public:
\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
used).
\throws Whatever <code>T::T(const T&)</code> throws.
Whatever <code>T::T(const T&)</code> throws.
\par Exception Safety
Basic.
\par Iterator Invalidation
@ -630,7 +691,8 @@ public:
\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
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
Basic.
\par Iterator Invalidation
@ -670,7 +732,8 @@ public:
\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
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
Basic.
\par Iterator Invalidation
@ -692,7 +755,7 @@ public:
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
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
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
this feature you have to turn the <a href="circular_buffer.html#debug">Debug Support</a> off otherwise an
assertion will report an error if such invalidated iterator is used.)
this feature you have to turn the __debug_support off by defining macro BOOST_CB_DISABLE_DEBUG,
otherwise an assertion will report an error if such invalidated iterator is used.)
\par Complexity
Constant (in the size of the <code>circular_buffer_space_optimized</code>).
\sa <code>\link swap(circular_buffer<T, Alloc>&, circular_buffer<T, Alloc>&)
swap(circular_buffer_space_optimized<T, Alloc>&, circular_buffer_space_optimized<T, Alloc>&)\endlink</code>
\sa <code>swap(circular_buffer<T, Alloc>&, circular_buffer<T, Alloc>&)</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);
circular_buffer<T, Alloc>::swap(cb);
}
@ -725,7 +792,7 @@ public:
\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).
\throws Whatever <code>T::T(const T&)</code> throws.
Whatever <code>T::T(const T&)</code> throws.
\par Exception Safety
Basic.
\par Iterator Invalidation
@ -736,11 +803,60 @@ public:
\sa <code>\link push_front() push_front(const_reference)\endlink</code>, <code>pop_back()</code>,
<code>pop_front()</code>
*/
void push_back(param_value_type item = value_type()) {
void push_back(param_value_type item) {
check_low_capacity();
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.
/*!
\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.
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
used).
\throws Whatever <code>T::T(const T&)</code> throws.
Whatever <code>T::T(const T&)</code> throws.
\par Exception Safety
Basic.
\par Iterator Invalidation
@ -761,11 +877,61 @@ public:
\sa <code>\link push_back() push_back(const_reference)\endlink</code>, <code>pop_back()</code>,
<code>pop_front()</code>
*/
void push_front(param_value_type item = value_type()) {
void push_front(param_value_type item) {
check_low_capacity();
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.
/*!
\pre <code>!empty()</code>
@ -826,8 +992,8 @@ public:
the <i>Effect</i>.)
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
used).
\throws Whatever <code>T::T(const T&)</code> throws.
\throws Whatever <code>T::operator = (const T&)</code> throws.
Whatever <code>T::T(const T&)</code> throws.
Whatever <code>T::operator = (const T&)</code> throws.
\par Exception Safety
Basic.
\par Iterator Invalidation
@ -843,12 +1009,88 @@ public:
rinsert(iterator, size_type, value_type)\endlink</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();
check_low_capacity();
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.
/*!
\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.
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
used).
\throws Whatever <code>T::T(const T&)</code> throws.
\throws Whatever <code>T::operator = (const T&)</code> throws.
Whatever <code>T::T(const T&)</code> throws.
Whatever <code>T::operator = (const T&)</code> throws.
\par Exception Safety
Basic.
\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
internal buffer may look like the one below.<br><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>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>
@ -911,8 +1153,7 @@ public:
\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
used).
\throws Whatever <code>T::T(const T&)</code> throws.
\throws Whatever <code>T::operator = (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
Basic.
\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
internal buffer may look like the one below.<br><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>
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
@ -962,8 +1203,8 @@ public:
the <i>Effect</i>.)
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
used).
\throws Whatever <code>T::T(const T&)</code> throws.
\throws Whatever <code>T::operator = (const T&)</code> throws.
Whatever <code>T::T(const T&)</code> throws.
Whatever <code>T::operator = (const T&)</code> throws.
\par Exception Safety
Basic.
\par Iterator Invalidation
@ -979,12 +1220,88 @@ public:
insert(iterator, size_type, value_type)\endlink</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();
check_low_capacity();
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.
/*!
\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.
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
used).
\throws Whatever <code>T::T(const T&)</code> throws.
\throws Whatever <code>T::operator = (const T&)</code> throws.
Whatever <code>T::T(const T&)</code> throws.
Whatever <code>T::operator = (const T&)</code> throws.
\par Exception Safety
Basic.
\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
internal buffer may look like the one below.<br><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>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>
@ -1048,8 +1365,8 @@ public:
\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
used).
\throws Whatever <code>T::T(const T&)</code> throws.
\throws Whatever <code>T::operator = (const T&)</code> throws.
Whatever <code>T::T(const T&)</code> throws.
Whatever <code>T::operator = (const T&)</code> throws.
\par Exception Safety
Basic.
\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
internal buffer may look like the one below.<br><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>
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
@ -1094,7 +1411,8 @@ public:
element exists.
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
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
Basic.
\par Iterator Invalidation
@ -1124,7 +1442,8 @@ public:
element exists.
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
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
Basic.
\par Iterator Invalidation
@ -1153,7 +1472,8 @@ public:
such element exists.
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
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
Basic.
\par Iterator Invalidation
@ -1162,7 +1482,7 @@ public:
\par Complexity
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
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>,
<code>rerase(iterator, iterator)</code>, <code>clear()</code>
*/
@ -1185,7 +1505,8 @@ public:
such element exists.
\throws "An allocation error" if memory is exhausted (<code>std::bad_alloc</code> if the standard allocator is
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
Basic.
\par Iterator Invalidation
@ -1195,7 +1516,7 @@ public:
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
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>,
<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.
template <class T, class Alloc>
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);
}

View File

@ -56,15 +56,8 @@
// get config suffix code:
#include <boost/config/suffix.hpp>
#ifdef BOOST_HAS_PRAGMA_ONCE
#pragma once
#endif
#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:
# define BOOST_LIB_TOOLSET "vc100"
# elif defined(BOOST_MSVC)
# elif defined(BOOST_MSVC) && (BOOST_MSVC < 1800)
// vc11:
# define BOOST_LIB_TOOLSET "vc110"
# elif defined(BOOST_MSVC)
// vc12:
# define BOOST_LIB_TOOLSET "vc120"
# elif defined(__BORLANDC__)
// 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
#endif

View File

@ -191,6 +191,9 @@
#define BOOST_NO_CXX11_NOEXCEPT
#define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX
#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
# define BOOST_HAS_TR1_HASH
@ -282,7 +285,3 @@
#define BOOST_NO_COMPLETE_VALUE_INITIALIZATION
#define BOOST_COMPILER "Borland C++ version " BOOST_STRINGIZE(__BORLANDC__)

View File

@ -8,6 +8,8 @@
// Clang compiler setup.
#define BOOST_HAS_PRAGMA_ONCE
#if !__has_feature(cxx_exceptions) && !defined(BOOST_NO_EXCEPTIONS)
# define BOOST_NO_EXCEPTIONS
#endif
@ -26,6 +28,14 @@
#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.
#define BOOST_HAS_LONG_LONG
@ -146,6 +156,18 @@
# define BOOST_NO_CXX11_USER_DEFINED_LITERALS
#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 extern templates

View File

@ -72,6 +72,12 @@
# endif
#endif
// Reportedly, #pragma once is supported since C++ Builder 2010
#if (__CODEGEARC__ >= 0x620)
# define BOOST_HAS_PRAGMA_ONCE
#endif
//
// C++0x macros:
//
@ -111,6 +117,9 @@
#define BOOST_NO_CXX11_VARIADIC_TEMPLATES
#define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX
#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:

View File

@ -54,6 +54,11 @@
# define BOOST_NO_LONG_LONG
# 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
//
@ -96,6 +101,9 @@
#define BOOST_NO_CXX11_VARIADIC_TEMPLATES
#define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX
#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
// EDG has "long long" in non-strict mode

View File

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

View File

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

View File

@ -20,51 +20,12 @@
#define BOOST_GCC (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__)
#endif
#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 __GNUC__ == 3
# if defined (__PATHSCALE__)
# define BOOST_NO_TWO_PHASE_NAME_LOOKUP
# define BOOST_NO_IS_ABSTRACT
# 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
# define BOOST_NO_IS_ABSTRACT
# endif
@ -80,6 +41,11 @@
# 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 )
// Previous versions of GCC did not completely implement value-initialization:
// 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
//
#if __GNUC__ > 3 || ( __GNUC__ == 3 && __GNUC_MINOR__ >= 1 )
#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
@ -127,13 +95,13 @@
// _WIN32 or one of its variant spellings. Note that Cygwin is a POSIX environment,
// so does not define _WIN32 or its variants.
# define BOOST_HAS_DECLSPEC
# define BOOST_SYMBOL_EXPORT __attribute__((dllexport))
# define BOOST_SYMBOL_IMPORT __attribute__((dllimport))
# define BOOST_SYMBOL_EXPORT __attribute__((__dllexport__))
# define BOOST_SYMBOL_IMPORT __attribute__((__dllimport__))
# else
# define BOOST_SYMBOL_EXPORT __attribute__((visibility("default")))
# define BOOST_SYMBOL_EXPORT __attribute__((__visibility__("default")))
# define BOOST_SYMBOL_IMPORT
# endif
# define BOOST_SYMBOL_VISIBLE __attribute__((visibility("default")))
# define BOOST_SYMBOL_VISIBLE __attribute__((__visibility__("default")))
#else
// config/platform/win32.hpp will define BOOST_SYMBOL_EXPORT, etc., unless already defined
# define BOOST_SYMBOL_EXPORT
@ -202,12 +170,19 @@
# define BOOST_NO_CXX11_HDR_INITIALIZER_LIST
# define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS
# define BOOST_NO_CXX11_DELETED_FUNCTIONS
# define BOOST_NO_CXX11_TRAILING_RESULT_TYPES
# define BOOST_NO_CXX11_INLINE_NAMESPACES
#endif
#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 5)
# define BOOST_NO_SFINAE_EXPR
#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
//
#if __GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 5) || !defined(__GXX_EXPERIMENTAL_CXX0X__)
@ -243,6 +218,12 @@
# define BOOST_NO_CXX11_USER_DEFINED_LITERALS
#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
//
#if (__GNUC__*10000 + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__ < 40801) || !defined(__GXX_EXPERIMENTAL_CXX0X__)
@ -261,8 +242,8 @@
#endif
// versions check:
// we don't know gcc prior to version 2.90:
#if (__GNUC__ == 2) && (__GNUC_MINOR__ < 90)
// we don't know gcc prior to version 3.30:
#if (__GNUC__ < 3) || (__GNUC__ == 3 && (__GNUC_MINOR__ < 3))
# error "Compiler not configured - please reconfigure"
#endif
//

View File

@ -55,6 +55,9 @@
# define BOOST_NO_CXX11_NOEXCEPT
# define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX
# 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__

View File

@ -119,6 +119,9 @@
#define BOOST_NO_CXX11_UNICODE_LITERALS
#define BOOST_NO_CXX11_VARIADIC_TEMPLATES
#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

View File

@ -27,7 +27,7 @@
#endif
// 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
#endif
#if defined(_MSC_VER) && (_MSC_VER >= 1600)
@ -47,11 +47,6 @@
# define BOOST_INTEL_LINUX BOOST_INTEL
#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 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
# 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:
#define BOOST_NO_TWO_PHASE_NAME_LOOKUP
#endif
@ -154,10 +149,18 @@ template<> struct assert_intrinsic_wchar_t<unsigned short> {};
# define BOOST_HAS_NRVO
#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:
// we don't support Intel prior to version 5.0:
#if BOOST_INTEL_CXX_VERSION < 500
// we don't support Intel prior to version 6.0:
#if BOOST_INTEL_CXX_VERSION < 600
# error "Compiler not supported or configured - please reconfigure"
#endif
@ -221,6 +224,7 @@ template<> struct assert_intrinsic_wchar_t<unsigned short> {};
# undef BOOST_NO_CXX11_DECLTYPE
# undef BOOST_NO_CXX11_AUTO_DECLARATIONS
# undef BOOST_NO_CXX11_AUTO_MULTIDECLARATIONS
# undef BOOST_NO_CXX11_TRAILING_RESULT_TYPES
#endif
// 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"
//# undef BOOST_NO_CXX11_SCOPED_ENUMS
#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)
//
@ -247,6 +287,9 @@ template<> struct assert_intrinsic_wchar_t<unsigned short> {};
# define BOOST_NO_CXX11_DELETED_FUNCTIONS
# define BOOST_NO_CXX11_DEFAULTED_FUNCTIONS
# define BOOST_NO_CXX11_TEMPLATE_ALIASES
# if(BOOST_INTEL_CXX_VERSION < 1310)
# define BOOST_NO_CXX11_TRAILING_RESULT_TYPES
# endif
#endif
#if (BOOST_INTEL_CXX_VERSION < 1200)
@ -256,9 +299,17 @@ template<> struct assert_intrinsic_wchar_t<unsigned short> {};
# define BOOST_NO_FENV_H
#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:
#if (BOOST_INTEL_CXX_VERSION > 1200)
#if (BOOST_INTEL_CXX_VERSION > 1310)
# if defined(BOOST_ASSERT_CONFIG)
# error "Unknown compiler version - please run the configure tests and report the results"
# elif defined(_MSC_VER)

View File

@ -120,6 +120,9 @@
#define BOOST_NO_CXX11_VARIADIC_MACROS
#define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX
#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)

View File

@ -69,6 +69,9 @@
#define BOOST_NO_CXX11_VARIADIC_MACROS
#define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX
#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:

View File

@ -14,15 +14,3 @@
// NVIDIA Specific support
// BOOST_GPU_ENABLED : Flag a function or a method as being enabled on the host and 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_CHRONO
# 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

View File

@ -41,6 +41,9 @@
#define BOOST_HAS_THREADS
#define BOOST_HAS_NRVO
#define BOOST_HAS_LONG_LONG
#if defined(linux) || defined(__linux) || defined(__linux__)
# define BOOST_HAS_STDINT_H
#endif
// options --enable-test wants undefined
#undef BOOST_NO_STDC_NAMESPACE
@ -112,6 +115,9 @@
#define BOOST_NO_CXX11_HDR_CHRONO
#define BOOST_NO_CXX11_HDR_ARRAY
#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:

View File

@ -128,6 +128,9 @@
#define BOOST_NO_CXX11_VARIADIC_MACROS
#define BOOST_NO_CXX11_UNIFIED_INITIALIZATION_SYNTAX
#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

View File

@ -126,6 +126,6 @@
#if ! __C99_MACRO_WITH_VA_ARGS
# define BOOST_NO_CXX11_VARIADIC_MACROS
#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):
#pragma warning( disable : 4503 ) // warning: decorated name length exceeded
#define BOOST_HAS_PRAGMA_ONCE
//
// versions check:
// we don't support Visual C++ prior to version 6:
#if _MSC_VER < 1200
// we don't support Visual C++ prior to version 7.1:
#if _MSC_VER < 1310
# error "Compiler not supported or configured - please reconfigure"
#endif
#if _MSC_VER < 1300 // 1200 == VC++ 6.0, 1200-1202 == eVC++4
# 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
#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
#if _MSC_FULL_VER < 180020827
# define BOOST_NO_FENV_H
#endif
#if _MSC_VER < 1400
@ -157,10 +110,8 @@
//
// __int64 support:
//
#if (_MSC_VER >= 1200)
# define BOOST_HAS_MS_INT64
#endif
#if (_MSC_VER >= 1310) && (defined(_MSC_EXTENSIONS) || (_MSC_VER >= 1400))
#define BOOST_HAS_MS_INT64
#if defined(_MSC_EXTENSIONS) || (_MSC_VER >= 1400)
# define BOOST_HAS_LONG_LONG
#else
# define BOOST_NO_LONG_LONG
@ -210,21 +161,23 @@
# define BOOST_HAS_STDINT_H
#endif
// C++ features supported by VC++ 11 (aka 2012)
// C++11 features supported by VC++ 11 (aka 2012)
//
#if _MSC_VER < 1700
# define BOOST_NO_CXX11_RANGE_BASED_FOR
# define BOOST_NO_CXX11_SCOPED_ENUMS
#endif // _MSC_VER < 1700
// C++11 features supported by VC++ 11 (aka 2012) November 2012 CTP
// Because the CTP is unsupported, unrelease, and only alpha quality,
// it is only supported if BOOST_MSVC_ENABLE_2012_NOV_CTP is defined.
// C++11 features supported by VC++ 12 (aka 2013).
//
#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_FUNCTION_TEMPLATE_DEFAULT_ARGS
# 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_UNIFIED_INITIALIZATION_SYNTAX
#endif
@ -234,14 +187,13 @@
#define BOOST_NO_CXX11_CHAR32_T
#define BOOST_NO_CXX11_CONSTEXPR
#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_TEMPLATE_ALIASES
#define BOOST_NO_CXX11_UNICODE_LITERALS
#define BOOST_NO_SFINAE_EXPR
#define BOOST_NO_TWO_PHASE_NAME_LOOKUP
#define BOOST_NO_CXX11_USER_DEFINED_LITERALS
#define BOOST_NO_CXX11_ALIGNAS
#define BOOST_NO_CXX11_INLINE_NAMESPACES
//
// prefix and suffix headers:
@ -261,11 +213,7 @@
// were shipped with freely downloadable SDKs, others as crosscompilers in eVC.
// IOW, you can't use these 'versions' in any sensible way. Sorry.
# if defined(UNDER_CE)
# if _MSC_VER < 1200
// 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
# if _MSC_VER < 1400
// Note: I'm not aware of any CE compiler with version 13xx
# if defined(BOOST_ASSERT_CONFIG)
# error "Unknown EVC++ compiler version - please run the configure tests and report the results"
@ -280,6 +228,8 @@
# define BOOST_COMPILER_VERSION evc10
# elif _MSC_VER < 1800
# define BOOST_COMPILER_VERSION evc11
# elif _MSC_VER < 1900
# define BOOST_COMPILER_VERSION evc12
# else
# if defined(BOOST_ASSERT_CONFIG)
# error "Unknown EVC++ compiler version - please run the configure tests and report the results"
@ -288,8 +238,8 @@
# endif
# endif
# else
# if _MSC_VER < 1200
// Note: these are so far off, they are not really supported
# if _MSC_VER < 1310
// Note: Versions up to 7.0 aren't supported.
# define BOOST_COMPILER_VERSION 5.0
# elif _MSC_VER < 1300
# define BOOST_COMPILER_VERSION 6.0
@ -305,6 +255,8 @@
# define BOOST_COMPILER_VERSION 10.0
# elif _MSC_VER < 1800
# define BOOST_COMPILER_VERSION 11.0
# elif _MSC_VER < 1900
# define BOOST_COMPILER_VERSION 12.0
# else
# define BOOST_COMPILER_VERSION _MSC_VER
# endif
@ -314,8 +266,8 @@
#endif
//
// last known and checked version is 1700 (VC11, aka 2011):
#if (_MSC_VER > 1700)
// last known and checked version is 18.00.20827.3 (VC12 RC, aka 2013 RC):
#if (_MSC_VER > 1800 && _MSC_FULL_VER > 180020827)
# if defined(BOOST_ASSERT_CONFIG)
# error "Unknown compiler version - please run the configure tests and report the results"
# else

View File

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

View File

@ -110,7 +110,8 @@
# define BOOST_NO_CXX11_SMART_PTR
#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
#endif
@ -128,10 +129,11 @@
# define BOOST_NO_CXX11_ATOMIC_SMART_PTR
#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
#endif
#ifdef _CPPLIB_VER
# define BOOST_DINKUMWARE_STDLIB _CPPLIB_VER

View File

@ -503,69 +503,8 @@ namespace boost{
#endif
// 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:
//
// #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
// These macros are obsolete. Port away and remove.
# define BOOST_EXPLICIT_TEMPLATE_TYPE(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_SPEC(t, v)
#endif // defined BOOST_NO_EXPLICIT_FUNCTION_TEMPLATE_ARGUMENTS
// When BOOST_NO_STD_TYPEINFO is defined, we can just import
// the global definition into std namespace:
#if defined(BOOST_NO_STD_TYPEINFO) && defined(__cplusplus)
@ -648,6 +584,78 @@ namespace std{ using ::type_info; }
# 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
//

View File

@ -17,12 +17,13 @@
#ifndef 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
#endif
#include <boost/container/detail/config_begin.hpp>
#include <boost/container/detail/workaround.hpp>
#include <boost/container/container_fwd.hpp>
#include <boost/intrusive/pointer_traits.hpp>
#include <boost/intrusive/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)
#include BOOST_PP_LOCAL_ITERATE()
#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)
///@endcond

View File

@ -11,7 +11,7 @@
#ifndef BOOST_CONTAINER_CONTAINER_FWD_HPP
#define BOOST_CONTAINER_CONTAINER_FWD_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
#if defined(_MSC_VER)
# pragma once
#endif
@ -135,20 +135,28 @@ class basic_string;
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
//! guaranteed to be ordered and unique
struct ordered_unique_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
//! guaranteed to be ordered and unique
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
namespace detail_really_deep_namespace {
@ -161,6 +169,7 @@ struct dummy
{
(void)ordered_range;
(void)ordered_unique_range;
(void)default_init;
}
};

View File

@ -13,7 +13,7 @@
#ifndef BOOST_CONTAINER_DETAIL_ALGORITHMS_HPP
#define BOOST_CONTAINER_DETAIL_ALGORITHMS_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
#if defined(_MSC_VER)
# pragma once
#endif
@ -35,13 +35,13 @@ namespace boost {
namespace container {
template<class It>
struct is_default_construct_iterator
struct is_value_init_construct_iterator
{
static const bool value = false;
};
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;
};
@ -64,11 +64,17 @@ inline void construct_in_place(A &a, T* dest, InpIt source)
//#endif
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);
}
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>
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
#define BOOST_CONTAINER_ALLOCATION_TYPE_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
#if defined(_MSC_VER)
# pragma once
#endif

View File

@ -11,7 +11,7 @@
#ifndef 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
#endif
@ -92,8 +92,12 @@ struct allocator_version_traits<Allocator, 1>
static void deallocate_individual(Allocator &a, multiallocation_chain &holder)
{
while(!holder.empty()){
a.deallocate(holder.pop_front(), 1);
size_type n = holder.size();
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 : 4671) // the copy constructor is inaccessible
#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

View File

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

View File

@ -14,7 +14,7 @@
#ifndef BOOST_CONTAINER_DETAIL_ITERATORS_HPP
#define BOOST_CONTAINER_DETAIL_ITERATORS_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
#if defined(_MSC_VER)
# pragma once
#endif
@ -23,6 +23,7 @@
#include <boost/move/utility.hpp>
#include <boost/container/allocator_traits.hpp>
#include <boost/container/detail/type_traits.hpp>
#include <boost/static_assert.hpp>
#ifdef BOOST_CONTAINER_PERFECT_FORWARDING
#include <boost/container/detail/variadic_templates_tools.hpp>
@ -147,79 +148,79 @@ class constant_iterator
};
template <class T, class Difference = std::ptrdiff_t>
class default_construct_iterator
class value_init_construct_iterator
: public std::iterator
<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:
explicit default_construct_iterator(Difference range_size)
explicit value_init_construct_iterator(Difference range_size)
: m_num(range_size){}
//Constructors
default_construct_iterator()
value_init_construct_iterator()
: m_num(0){}
default_construct_iterator& operator++()
value_init_construct_iterator& operator++()
{ 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();
return result;
}
default_construct_iterator& operator--()
value_init_construct_iterator& operator--()
{ 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();
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); }
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); }
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); }
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; }
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); }
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); }
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); }
//Arithmetic
default_construct_iterator& operator+=(Difference off)
value_init_construct_iterator& operator+=(Difference off)
{ 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);
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; }
default_construct_iterator& operator-=(Difference off)
value_init_construct_iterator& operator-=(Difference off)
{ this->advance(-off); return *this; }
default_construct_iterator operator-(Difference off) const
value_init_construct_iterator operator-(Difference off) const
{ return *this + (-off); }
//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; }
};
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>
class repeat_iterator
: public std::iterator
@ -585,24 +698,112 @@ struct is_bidirectional_iterator<T, false>
static const bool value = false;
};
template<class T, class IIterator>
template<class IIterator>
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>::difference_type difference_type;
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>::
template rebind_pointer<const T>::type const_pointer;
template rebind_pointer<const value_type>::type const_pointer;
typedef typename ::boost::intrusive::
pointer_traits<pointer>::reference reference;
typedef typename ::boost::intrusive::
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 {
} //namespace boost {

View File

@ -11,7 +11,7 @@
#ifndef 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
#endif

View File

@ -13,7 +13,7 @@
#ifndef 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
#endif

View File

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

View File

@ -11,7 +11,7 @@
#ifndef 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
#endif
@ -28,6 +28,7 @@
#include <boost/container/detail/type_traits.hpp>
#include <boost/container/detail/utilities.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/destroyers.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::key_of_value key_of_value;
node_compare(const ValueCompare &pred)
explicit node_compare(const ValueCompare &pred)
: ValueCompare(pred)
{}
node_compare()
: ValueCompare()
{}
ValueCompare &value_comp()
{ return static_cast<ValueCompare &>(*this); }
@ -67,16 +72,16 @@ struct node_compare
{ 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
{
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 ICont::value_type Node;
typedef typename allocator_traits_type::template
portable_rebind_alloc<Node>::type NodeAlloc;
typedef allocator_traits<NodeAlloc> node_allocator_traits_type;
typedef container_detail::allocator_version_traits<NodeAlloc> node_allocator_version_traits_type;
typedef A ValAlloc;
typedef typename node_allocator_traits_type::pointer NodePtr;
typedef container_detail::scoped_deallocator<NodeAlloc> Deallocator;
@ -116,20 +121,20 @@ struct node_alloc_holder
{ this->icont().swap(x.icont()); }
//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)
{}
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)
{}
explicit node_alloc_holder(const Pred &c)
explicit node_alloc_holder(const ValPred &c)
: members_(c)
{}
//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)
{ this->icont().swap(x.icont()); }
@ -230,45 +235,41 @@ struct node_alloc_holder
(FwdIterator beg, difference_type n, Inserter inserter)
{
if(n){
/*
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;
typedef typename node_allocator_version_traits_type::multiallocation_chain multiallocation_chain;
//Try to allocate memory in a single block
typedef typename multiallocation_chain::iterator multialloc_iterator;
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());
mem.clear();
Node *p = 0;
NodeAlloc &nalloc = this->node_alloc();
BOOST_TRY{
Deallocator node_deallocator(NodePtr(), nalloc);
container_detail::scoped_destructor<NodeAlloc> sdestructor(nalloc, 0);
while(n--){
p = container_detail::to_raw_pointer(&*itbeg);
node_deallocator.set(p);
++itbeg;
//This can throw
Deallocator node_deallocator(p, nalloc);
boost::container::construct_in_place(nalloc, container_detail::addressof(p->m_data), beg);
sdestructor.set(p);
++beg;
node_deallocator.release();
//This does not throw
typedef typename Node::hook_type 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);
sdestructor.set(0);
}
sdestructor.release();
node_deallocator.release();
}
BOOST_CATCH(...){
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_CATCH_END
@ -345,12 +346,12 @@ struct node_alloc_holder
{}
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))
, m_icont(typename ICont::value_compare(c))
{}
explicit members_holder(const Pred &c)
explicit members_holder(const ValPred &c)
: NodeAlloc()
, m_icont(typename ICont::value_compare(c))
{}

View File

@ -13,7 +13,7 @@
#ifndef 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
#endif

View File

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

View File

@ -14,7 +14,7 @@
#ifndef 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
#endif

View File

@ -20,8 +20,8 @@
#include <boost/type_traits/has_trivial_destructor.hpp>
#include <boost/detail/no_exceptions_support.hpp>
#include <boost/intrusive/rbtree.hpp>
#include <boost/container/detail/utilities.hpp>
#include <boost/container/detail/iterators.hpp>
#include <boost/container/detail/algorithms.hpp>
#include <boost/container/detail/node_alloc_holder.hpp>
#include <boost/container/detail/destroyers.hpp>
@ -50,8 +50,12 @@ struct tree_value_compare
typedef KeyOfValue key_of_value;
typedef Key key_type;
tree_value_compare(const key_compare &kcomp)
: key_compare(kcomp)
explicit tree_value_compare(const key_compare &kcomp)
: KeyCompare(kcomp)
{}
tree_value_compare()
: KeyCompare()
{}
const key_compare &key_comp() const
@ -174,6 +178,34 @@ struct rbtree_node
{ 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 {
@ -212,15 +244,15 @@ class rbtree
, typename container_detail::intrusive_rbtree_type
<A, tree_value_compare<Key, Value, KeyCompare, KeyOfValue>
>::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
< A, tree_value_compare
<Key, Value, KeyCompare, KeyOfValue>
>::type Icont;
< A, ValComp>::type Icont;
typedef container_detail::node_alloc_holder
<A, Icont, KeyCompare> AllocHolder;
<A, Icont, ValComp> AllocHolder;
typedef typename AllocHolder::NodePtr NodePtr;
typedef rbtree < Key, Value, KeyOfValue
, KeyCompare, A> ThisType;
@ -318,8 +350,7 @@ class rbtree
typedef Value value_type;
typedef A allocator_type;
typedef KeyCompare key_compare;
typedef tree_value_compare< Key, Value
, KeyCompare, KeyOfValue> value_compare;
typedef ValComp value_compare;
typedef typename boost::container::
allocator_traits<A>::pointer pointer;
typedef typename boost::container::
@ -373,109 +404,21 @@ class rbtree
typedef key_node_compare<value_compare> KeyNodeCompare;
public:
//rbtree const_iterator
class 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 container_detail::iterator<iiterator, false> iterator;
typedef container_detail::iterator<iiterator, true > const_iterator;
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
rbtree()
: AllocHolder(key_compare())
: AllocHolder(ValComp(key_compare()))
{}
rbtree(const key_compare& comp, const allocator_type& a = allocator_type())
: AllocHolder(a, comp)
explicit rbtree(const key_compare& comp, const allocator_type& a = allocator_type())
: AllocHolder(a, ValComp(comp))
{}
explicit rbtree(const allocator_type& a)
: AllocHolder(a)
{}
template <class InputIterator>
@ -488,13 +431,21 @@ class rbtree
>::type * = 0
#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){
this->insert_unique(first, last);
for ( ; first != last; ++first){
this->insert_unique(end_it, *first);
}
}
else{
this->insert_equal(first, last);
for ( ; first != last; ++first){
this->insert_equal(end_it, *first);
}
}
}
@ -508,15 +459,22 @@ class rbtree
>::type * = 0
#endif
)
: AllocHolder(a, comp)
: AllocHolder(a, value_compare(comp))
{
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{
//Optimized allocation and construction
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
#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>
@ -545,33 +505,34 @@ class rbtree
>::type * = 0
#endif
)
: AllocHolder(a, comp)
: AllocHolder(a, value_compare(comp))
{
//Optimized allocation and construction
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)
: AllocHolder(x, x.key_comp())
: AllocHolder(x, x.value_comp())
{
this->icont().clone_from
(x.icont(), typename AllocHolder::cloner(*this), Destroyer(this->node_alloc()));
}
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)
: AllocHolder(a, x.key_comp())
: AllocHolder(a, x.value_comp())
{
this->icont().clone_from
(x.icont(), typename AllocHolder::cloner(*this), Destroyer(this->node_alloc()));
}
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()){
this->icont().swap(x.icont());
@ -619,8 +580,8 @@ class rbtree
rbtree& operator=(BOOST_RV_REF(rbtree) x)
{
if (&x != this){
NodeAlloc &this_alloc = this->node_alloc();
NodeAlloc &x_alloc = x.node_alloc();
NodeAlloc &this_alloc = this->get_stored_allocator();
const NodeAlloc &x_alloc = x.get_stored_allocator();
//If allocators are equal we can just swap pointers
if(this_alloc == x_alloc){
//Destroy and swap pointers
@ -763,8 +724,10 @@ class rbtree
iterator insert_unique_commit(const value_type& v, insert_commit_data &data)
{
NodePtr tmp = AllocHolder::create_node(v);
iiterator it(this->icont().insert_unique_commit(*tmp, data));
return iterator(it);
scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
iterator ret(this->icont().insert_unique_commit(*tmp, data));
destroy_deallocator.release();
return ret;
}
template<class MovableConvertible>
@ -772,8 +735,10 @@ class rbtree
(BOOST_FWD_REF(MovableConvertible) mv, insert_commit_data &data)
{
NodePtr tmp = AllocHolder::create_node(boost::forward<MovableConvertible>(mv));
iiterator it(this->icont().insert_unique_commit(*tmp, data));
return iterator(it);
scoped_destroy_deallocator<NodeAlloc> destroy_deallocator(tmp, this->node_alloc());
iterator ret(this->icont().insert_unique_commit(*tmp, data));
destroy_deallocator.release();
return ret;
}
std::pair<iterator,bool> insert_unique(const value_type& v)
@ -781,10 +746,10 @@ class rbtree
insert_commit_data data;
std::pair<iterator,bool> ret =
this->insert_unique_check(KeyOfValue()(v), data);
if(!ret.second)
if(ret.second){
ret.first = this->insert_unique_commit(v, data);
}
return ret;
return std::pair<iterator,bool>
(this->insert_unique_commit(v, data), true);
}
template<class MovableConvertible>
@ -793,13 +758,22 @@ class rbtree
insert_commit_data data;
std::pair<iterator,bool> ret =
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 std::pair<iterator,bool>
(this->insert_unique_commit(boost::forward<MovableConvertible>(mv), data), true);
}
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)
{
value_type &v = p->get_data();
@ -845,15 +819,21 @@ class rbtree
template <class... Args>
iterator emplace_equal(Args&&... args)
{
NodePtr p(AllocHolder::create_node(boost::forward<Args>(args)...));
return iterator(this->icont().insert_equal(this->icont().end(), *p));
NodePtr tmp(AllocHolder::create_node(boost::forward<Args>(args)...));
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>
iterator emplace_hint_equal(const_iterator hint, Args&&... args)
{
NodePtr p(AllocHolder::create_node(boost::forward<Args>(args)...));
return iterator(this->icont().insert_equal(hint.get(), *p));
NodePtr tmp(AllocHolder::create_node(boost::forward<Args>(args)...));
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
@ -877,16 +857,22 @@ class rbtree
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, _)) \
{ \
NodePtr p(AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \
return iterator(this->icont().insert_equal(this->icont().end(), *p)); \
NodePtr tmp(AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \
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, >) \
iterator emplace_hint_equal(const_iterator hint \
BOOST_PP_ENUM_TRAILING(n, BOOST_CONTAINER_PP_PARAM_LIST, _)) \
{ \
NodePtr p(AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \
return iterator(this->icont().insert_equal(hint.get(), *p)); \
NodePtr tmp(AllocHolder::create_node(BOOST_PP_ENUM(n, BOOST_CONTAINER_PP_PARAM_FORWARD, _))); \
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)
@ -918,53 +904,53 @@ class rbtree
template <class InputIterator>
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)
this->insert_unique(*first);
}
}
iterator insert_equal(const value_type& v)
{
NodePtr p(AllocHolder::create_node(v));
return iterator(this->icont().insert_equal(this->icont().end(), *p));
NodePtr tmp(AllocHolder::create_node(v));
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>
iterator insert_equal(BOOST_FWD_REF(MovableConvertible) mv)
{
NodePtr p(AllocHolder::create_node(boost::forward<MovableConvertible>(mv)));
return iterator(this->icont().insert_equal(this->icont().end(), *p));
NodePtr tmp(AllocHolder::create_node(boost::forward<MovableConvertible>(mv)));
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)
{
NodePtr p(AllocHolder::create_node(v));
return iterator(this->icont().insert_equal(hint.get(), *p));
NodePtr tmp(AllocHolder::create_node(v));
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>
iterator insert_equal(const_iterator hint, BOOST_FWD_REF(MovableConvertible) mv)
{
NodePtr p(AllocHolder::create_node(boost::forward<MovableConvertible>(mv)));
return iterator(this->icont().insert_equal(hint.get(), *p));
NodePtr tmp(AllocHolder::create_node(boost::forward<MovableConvertible>(mv)));
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>
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)
hint = this->insert_equal(hint, *first);
this->insert_equal(*first);
}
iterator erase(const_iterator position)
@ -1015,41 +1001,6 @@ class rbtree
return std::pair<const_iterator,const_iterator>
(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,

View File

@ -15,7 +15,7 @@
#ifndef 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
#endif

View File

@ -12,6 +12,7 @@
#define BOOST_CONTAINER_DETAIL_UTILITIES_HPP
#include "config_begin.hpp"
#include "workaround.hpp"
#include <cstdio>
#include <cstring> //for ::memcpy
#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
<typename A,
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;
BOOST_TRY{
@ -654,6 +655,41 @@ inline F uninitialized_default_alloc_n(A &a, typename allocator_traits<A>::diffe
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
@ -1055,18 +1091,21 @@ inline typename container_detail::enable_if_c
::memcpy(short_ptr, stora_ptr, sizeof_storage);
large_ptr += sizeof_storage;
short_ptr += sizeof_storage;
BOOST_CONTAINER_FALLTHOUGH
case 3:
::memcpy(stora_ptr, large_ptr, sizeof_storage);
::memcpy(large_ptr, short_ptr, sizeof_storage);
::memcpy(short_ptr, stora_ptr, sizeof_storage);
large_ptr += sizeof_storage;
short_ptr += sizeof_storage;
BOOST_CONTAINER_FALLTHOUGH
case 2:
::memcpy(stora_ptr, large_ptr, sizeof_storage);
::memcpy(large_ptr, short_ptr, sizeof_storage);
::memcpy(short_ptr, stora_ptr, sizeof_storage);
large_ptr += sizeof_storage;
short_ptr += sizeof_storage;
BOOST_CONTAINER_FALLTHOUGH
case 1:
::memcpy(stora_ptr, large_ptr, sizeof_storage);
::memcpy(large_ptr, short_ptr, sizeof_storage);

View File

@ -13,7 +13,7 @@
#ifndef 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
#endif

View File

@ -11,7 +11,7 @@
#ifndef 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
#endif

View File

@ -35,6 +35,12 @@
#define BOOST_CONTAINER_UNIMPLEMENTED_PACK_EXPANSION_TO_FIXED_LIST
#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
#define BOOST_CONTAINER_IMPDEF(TYPE) TYPE
#define BOOST_CONTAINER_SEEDOC(TYPE) TYPE

View File

@ -11,7 +11,7 @@
#ifndef BOOST_CONTAINER_MAP_HPP
#define BOOST_CONTAINER_MAP_HPP
#if (defined _MSC_VER) && (_MSC_VER >= 1200)
#if defined(_MSC_VER)
# pragma once
#endif
@ -138,6 +138,16 @@ class map
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
//! allocator, and inserts elements from the range [first ,last ).
//!
@ -160,6 +170,8 @@ class map
//! unique values.
//!
//! <b>Complexity</b>: Linear in N.
//!
//! <b>Note</b>: Non-standard extension.
template <class InputIterator>
map( ordered_unique_range_t, InputIterator first, InputIterator last
, const Compare& comp = Compare(), const allocator_type& a = allocator_type())
@ -701,7 +713,7 @@ class map
//!
//! <b>Complexity</b>: log(size())+count(k)
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
//! 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));
}
//! <b>Effects</b>: Constructs an empty multimap using the specified comparison
//! object and allocator.
//! <b>Effects</b>: Constructs an empty multimap using the specified allocator.
//!
//! <b>Complexity</b>: Constant.
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));
}
//! <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
//! 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>Complexity</b>: Linear in N.
//!
//! <b>Note</b>: Non-standard extension.
template <class InputIterator>
multimap(ordered_range_t, InputIterator first, InputIterator last, const Compare& comp = Compare(),
const allocator_type& a = allocator_type())

View File

@ -17,7 +17,7 @@
#ifndef 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
#endif
@ -585,6 +585,8 @@ class scoped_allocator_adaptor_base
typedef OuterAlloc outer_allocator_type;
typedef scoped_allocator_adaptor<InnerAllocs...> inner_allocator_type;
typedef allocator_traits<inner_allocator_type> inner_traits_type;
typedef scoped_allocator_adaptor
<OuterAlloc, InnerAllocs...> scoped_allocator_type;
typedef boost::integral_constant<
bool,
outer_traits_type::propagate_on_container_copy_assignment::value ||
@ -635,7 +637,7 @@ class scoped_allocator_adaptor_base
, m_inner(other.inner_allocator())
{}
protected:
public:
struct internal_type_t{};
template <class OuterA2>
@ -670,6 +672,9 @@ class scoped_allocator_adaptor_base
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()
{ return m_inner; }
@ -682,6 +687,15 @@ class scoped_allocator_adaptor_base
const outer_allocator_type &outer_allocator() const
{ 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:
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_CONTAINER_PP_IDENTITY, nat) \
> 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 boost::integral_constant< \
bool, \
@ -790,7 +809,7 @@ class scoped_allocator_adaptor_base<OuterAlloc, true
, m_inner(other.inner_allocator()) \
{} \
\
protected: \
public: \
struct internal_type_t{}; \
\
template <class OuterA2> \
@ -824,6 +843,9 @@ class scoped_allocator_adaptor_base<OuterAlloc, true
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() \
{ return m_inner; } \
\
@ -836,6 +858,14 @@ class scoped_allocator_adaptor_base<OuterAlloc, true
const outer_allocator_type &outer_allocator() const \
{ 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: \
inner_allocator_type m_inner; \
}; \
@ -874,6 +904,7 @@ class scoped_allocator_adaptor_base
typedef OuterAlloc outer_allocator_type;
typedef allocator_traits<OuterAlloc> outer_traits_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 typename outer_traits_type::
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())
{}
protected:
public:
struct internal_type_t{};
template <class OuterA2>
@ -948,6 +979,9 @@ class scoped_allocator_adaptor_base
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()
{ return static_cast<inner_allocator_type&>(*this); }
@ -959,6 +993,17 @@ class scoped_allocator_adaptor_base
const outer_allocator_type &outer_allocator() const
{ 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 {
@ -1164,48 +1209,37 @@ class scoped_allocator_adaptor
{}
scoped_allocator_adaptor &operator=(BOOST_COPY_ASSIGN_REF(scoped_allocator_adaptor) other)
{
base_type::operator=(static_cast<const base_type &>(other));
return *this;
}
{ return static_cast<scoped_allocator_adaptor&>(base_type::operator=(static_cast<const base_type &>(other))); }
scoped_allocator_adaptor &operator=(BOOST_RV_REF(scoped_allocator_adaptor) other)
{
base_type::operator=(boost::move(static_cast<scoped_allocator_adaptor&>(other)));
return *this;
}
{ return static_cast<scoped_allocator_adaptor&>(base_type::operator=(boost::move(static_cast<base_type&>(other)))); }
#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.
//!
void swap(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); }
friend void swap(scoped_allocator_adaptor &l, scoped_allocator_adaptor &r);
//! <b>Returns</b>:
//! `static_cast<OuterAlloc&>(*this)`.
outer_allocator_type & outer_allocator()
{ return *this; }
outer_allocator_type & outer_allocator();
//! <b>Returns</b>:
//! `static_cast<const OuterAlloc&>(*this)`.
const outer_allocator_type &outer_allocator() const
{ return *this; }
const outer_allocator_type &outer_allocator() const;
//! <b>Returns</b>:
//! *this if `sizeof...(InnerAllocs)` is zero; otherwise, inner.
inner_allocator_type& inner_allocator()
{ return base_type::inner_allocator(); }
inner_allocator_type& inner_allocator();
//! <b>Returns</b>:
//! *this if `sizeof...(InnerAllocs)` is zero; otherwise, inner.
inner_allocator_type const& inner_allocator() const
{ return base_type::inner_allocator(); }
inner_allocator_type const& inner_allocator() const;
#endif //BOOST_CONTAINER_DOXYGEN_INVOKED
//! <b>Returns</b>:
//! `allocator_traits<OuterAlloc>::max_size(outer_allocator())`.
@ -1244,18 +1278,14 @@ class scoped_allocator_adaptor
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
//! A in the adaptor is initialized from the result of calling
//! `allocator_traits<Allocator>::select_on_container_copy_construction()` on
//! the corresponding allocator in *this.
scoped_allocator_adaptor select_on_container_copy_construction() const
{
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())
);
}
scoped_allocator_adaptor select_on_container_copy_construction() const;
#endif //BOOST_CONTAINER_DOXYGEN_INVOKED
/// @cond
base_type &base() { return *this; }
@ -1426,7 +1456,8 @@ class scoped_allocator_adaptor
//template <class T1, class T2, class... Args1, class... Args2>
//void construct(pair<T1, T2>* p, piecewise_construct_t, tuple<Args1...> x, tuple<Args2...> y);
private:
public:
//Internal function
template <class OuterA2>
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)

View File

@ -11,7 +11,7 @@
#ifndef 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
#endif

View File

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

View File

@ -361,6 +361,40 @@ namespace boost
#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

View File

@ -7,7 +7,7 @@
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* 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());
while (itr != format_str.end() && (sitr != stream_end)) {
if (*itr == '%') {
itr++;
if ( ++itr == format_str.end())
break;
if (*itr != '%') {
switch(*itr) {
case 'a':
@ -476,7 +477,8 @@ class format_date_parser
const_itr itr(format_str.begin());
while (itr != format_str.end() && (sitr != stream_end)) {
if (*itr == '%') {
itr++;
if ( ++itr == format_str.end())
break;
if (*itr != '%') {
switch(*itr) {
case 'b':
@ -577,7 +579,8 @@ class format_date_parser
const_itr itr(format_str.begin());
while (itr != format_str.end() && (sitr != stream_end)) {
if (*itr == '%') {
itr++;
if ( ++itr == format_str.end())
break;
if (*itr != '%') {
switch(*itr) {
case 'a':
@ -666,7 +669,8 @@ class format_date_parser
const_itr itr(format_str.begin());
while (itr != format_str.end() && (sitr != stream_end)) {
if (*itr == '%') {
itr++;
if ( ++itr == format_str.end())
break;
if (*itr != '%') {
//match_results mr;
switch(*itr) {

View File

@ -6,7 +6,7 @@
* Boost Software License, Version 1.0. (See accompanying
* file LICENSE_1_0.txt or http://www.boost.org/LICENSE_1_0.txt)
* 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>

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