summaryrefslogtreecommitdiff
path: root/boost/core
diff options
context:
space:
mode:
Diffstat (limited to 'boost/core')
-rw-r--r--boost/core/addressof.hpp301
-rw-r--r--boost/core/demangle.hpp13
-rw-r--r--boost/core/lightweight_test.hpp191
3 files changed, 396 insertions, 109 deletions
diff --git a/boost/core/addressof.hpp b/boost/core/addressof.hpp
index 889b5825e1..0a2b46be77 100644
--- a/boost/core/addressof.hpp
+++ b/boost/core/addressof.hpp
@@ -1,162 +1,265 @@
-// Copyright (C) 2002 Brad King (brad.king@kitware.com)
-// Douglas Gregor (gregod@cs.rpi.edu)
-//
-// Copyright (C) 2002, 2008, 2013 Peter Dimov
-//
-// 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) 2002 Brad King (brad.king@kitware.com)
+ Douglas Gregor (gregod@cs.rpi.edu)
-// For more information, see http://www.boost.org
+Copyright (C) 2002, 2008, 2013 Peter Dimov
+
+Copyright (C) 2017 Glen Joseph Fernandes (glenjofe@gmail.com)
+
+Distributed under the Boost Software License, Version 1.0.
+(See accompanying file LICENSE_1_0.txt or copy at
+http://www.boost.org/LICENSE_1_0.txt)
+*/
#ifndef BOOST_CORE_ADDRESSOF_HPP
#define BOOST_CORE_ADDRESSOF_HPP
-# include <boost/config.hpp>
-# include <boost/detail/workaround.hpp>
-# include <cstddef>
+#include <boost/config.hpp>
-namespace boost
-{
+#if defined(BOOST_MSVC_FULL_VER) && BOOST_MSVC_FULL_VER >= 190024215
+#define BOOST_CORE_HAS_BUILTIN_ADDRESSOF
+#elif defined(BOOST_GCC) && BOOST_GCC >= 70000
+#define BOOST_CORE_HAS_BUILTIN_ADDRESSOF
+#elif defined(__has_builtin)
+#if __has_builtin(__builtin_addressof)
+#define BOOST_CORE_HAS_BUILTIN_ADDRESSOF
+#endif
+#endif
-namespace detail
-{
+#if defined(BOOST_CORE_HAS_BUILTIN_ADDRESSOF)
+#if defined(BOOST_NO_CXX11_CONSTEXPR)
+#define BOOST_CORE_NO_CONSTEXPR_ADDRESSOF
+#endif
+
+namespace boost {
-template<class T> struct addr_impl_ref
+template<class T>
+BOOST_CONSTEXPR inline T*
+addressof(T& o) BOOST_NOEXCEPT
{
- T & v_;
+ return __builtin_addressof(o);
+}
- BOOST_FORCEINLINE addr_impl_ref( T & v ): v_( v ) {}
- BOOST_FORCEINLINE operator T& () const { return v_; }
+} /* boost */
+#else
+#include <boost/detail/workaround.hpp>
+#include <cstddef>
+namespace boost {
+namespace detail {
+
+template<class T>
+class addressof_ref {
+public:
+ BOOST_FORCEINLINE addressof_ref(T& o) BOOST_NOEXCEPT
+ : o_(o) { }
+ BOOST_FORCEINLINE operator T&() const BOOST_NOEXCEPT {
+ return o_;
+ }
private:
- addr_impl_ref & operator=(const addr_impl_ref &);
+ addressof_ref& operator=(const addressof_ref&);
+ T& o_;
};
-template<class T> struct addressof_impl
-{
- static BOOST_FORCEINLINE T * f( T & v, long )
- {
- return reinterpret_cast<T*>(
- &const_cast<char&>(reinterpret_cast<const volatile char &>(v)));
+template<class T>
+struct address_of {
+ static BOOST_FORCEINLINE T* get(T& o, long) BOOST_NOEXCEPT {
+ return reinterpret_cast<T*>(&
+ const_cast<char&>(reinterpret_cast<const volatile char&>(o)));
}
-
- static BOOST_FORCEINLINE T * f( T * v, int )
- {
- return v;
+ static BOOST_FORCEINLINE T* get(T* p, int) BOOST_NOEXCEPT {
+ return p;
}
};
-#if !defined( BOOST_NO_CXX11_NULLPTR )
-
-#if !defined( BOOST_NO_CXX11_DECLTYPE ) && ( ( defined( __clang__ ) && !defined( _LIBCPP_VERSION ) ) || defined( __INTEL_COMPILER ) )
-
- typedef decltype(nullptr) addr_nullptr_t;
-
+#if !defined(BOOST_NO_CXX11_NULLPTR)
+#if !defined(BOOST_NO_CXX11_DECLTYPE) && \
+ (defined(__INTEL_COMPILER) || \
+ (defined(__clang__) && !defined(_LIBCPP_VERSION)))
+typedef decltype(nullptr) addressof_null_t;
#else
-
- typedef std::nullptr_t addr_nullptr_t;
-
+typedef std::nullptr_t addressof_null_t;
#endif
-template<> struct addressof_impl< addr_nullptr_t >
-{
- typedef addr_nullptr_t T;
-
- static BOOST_FORCEINLINE T * f( T & v, int )
- {
- return &v;
+template<>
+struct address_of<addressof_null_t> {
+ typedef addressof_null_t type;
+ static BOOST_FORCEINLINE type* get(type& o, int) BOOST_NOEXCEPT {
+ return &o;
}
};
-template<> struct addressof_impl< addr_nullptr_t const >
-{
- typedef addr_nullptr_t const T;
-
- static BOOST_FORCEINLINE T * f( T & v, int )
- {
- return &v;
+template<>
+struct address_of<const addressof_null_t> {
+ typedef const addressof_null_t type;
+ static BOOST_FORCEINLINE type* get(type& o, int) BOOST_NOEXCEPT {
+ return &o;
}
};
-template<> struct addressof_impl< addr_nullptr_t volatile >
-{
- typedef addr_nullptr_t volatile T;
+template<>
+struct address_of<volatile addressof_null_t> {
+ typedef volatile addressof_null_t type;
+ static BOOST_FORCEINLINE type* get(type& o, int) BOOST_NOEXCEPT {
+ return &o;
+ }
+};
- static BOOST_FORCEINLINE T * f( T & v, int )
- {
- return &v;
+template<>
+struct address_of<const volatile addressof_null_t> {
+ typedef const volatile addressof_null_t type;
+ static BOOST_FORCEINLINE type* get(type& o, int) BOOST_NOEXCEPT {
+ return &o;
}
};
+#endif
+
+} /* detail */
-template<> struct addressof_impl< addr_nullptr_t const volatile >
+#if defined(BOOST_NO_CXX11_SFINAE_EXPR) || \
+ defined(BOOST_NO_CXX11_RVALUE_REFERENCES) || \
+ defined(BOOST_NO_CXX11_CONSTEXPR) || \
+ defined(BOOST_NO_CXX11_DECLTYPE)
+#define BOOST_CORE_NO_CONSTEXPR_ADDRESSOF
+
+template<class T>
+BOOST_FORCEINLINE T*
+addressof(T& o) BOOST_NOEXCEPT
{
- typedef addr_nullptr_t const volatile T;
+#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x610)) || \
+ BOOST_WORKAROUND(__SUNPRO_CC, <= 0x5120)
+ return detail::address_of<T>::get(o, 0);
+#else
+ return detail::address_of<T>::get(detail::addressof_ref<T>(o), 0);
+#endif
+}
- static BOOST_FORCEINLINE T * f( T & v, int )
- {
- return &v;
- }
+#if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x590))
+namespace detail {
+
+template<class T>
+struct addressof_result {
+ typedef T* type;
};
+} /* detail */
+
+template<class T, std::size_t N>
+BOOST_FORCEINLINE typename detail::addressof_result<T[N]>::type
+addressof(T (&o)[N]) BOOST_NOEXCEPT
+{
+ return &o;
+}
#endif
-} // namespace detail
+#if BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
+template<class T, std::size_t N>
+BOOST_FORCEINLINE
+T (*addressof(T (&o)[N]) BOOST_NOEXCEPT)[N]
+{
+ return reinterpret_cast<T(*)[N]>(&o);
+}
-template<class T>
+template<class T, std::size_t N>
BOOST_FORCEINLINE
-T * addressof( T & v )
+const T (*addressof(const T (&o)[N]) BOOST_NOEXCEPT)[N]
{
-#if (defined( __BORLANDC__ ) && BOOST_WORKAROUND( __BORLANDC__, BOOST_TESTED_AT( 0x610 ) ) ) || (defined(__SUNPRO_CC) && BOOST_WORKAROUND(__SUNPRO_CC, <= 0x5120))
+ return reinterpret_cast<const T(*)[N]>(&o);
+}
+#endif
+#else
+namespace detail {
- return boost::detail::addressof_impl<T>::f( v, 0 );
+template<class T>
+T&& addressof_declval() BOOST_NOEXCEPT;
-#else
+template<class>
+struct addressof_void {
+ typedef void type;
+};
- return boost::detail::addressof_impl<T>::f( boost::detail::addr_impl_ref<T>( v ), 0 );
+template<class T, class E = void>
+struct addressof_member_operator {
+ static constexpr bool value = false;
+};
+
+template<class T>
+struct addressof_member_operator<T, typename
+ addressof_void<decltype(addressof_declval<T&>().operator&())>::type> {
+ static constexpr bool value = true;
+};
+
+#if BOOST_WORKAROUND(BOOST_INTEL, < 1600)
+struct addressof_addressable { };
+addressof_addressable*
+operator&(addressof_addressable&) BOOST_NOEXCEPT;
#endif
-}
-#if defined( __SUNPRO_CC ) && BOOST_WORKAROUND( __SUNPRO_CC, BOOST_TESTED_AT( 0x590 ) )
+template<class T, class E = void>
+struct addressof_non_member_operator {
+ static constexpr bool value = false;
+};
-namespace detail
-{
+template<class T>
+struct addressof_non_member_operator<T, typename
+ addressof_void<decltype(operator&(addressof_declval<T&>()))>::type> {
+ static constexpr bool value = true;
+};
-template<class T> struct addressof_addp
-{
- typedef T * type;
+template<class T, class E = void>
+struct addressof_expression {
+ static constexpr bool value = false;
+};
+
+template<class T>
+struct addressof_expression<T,
+ typename addressof_void<decltype(&addressof_declval<T&>())>::type> {
+ static constexpr bool value = true;
+};
+
+template<class T>
+struct addressof_is_constexpr {
+ static constexpr bool value = addressof_expression<T>::value &&
+ !addressof_member_operator<T>::value &&
+ !addressof_non_member_operator<T>::value;
};
-} // namespace detail
+template<bool E, class T>
+struct addressof_if { };
+
+template<class T>
+struct addressof_if<true, T> {
+ typedef T* type;
+};
-template< class T, std::size_t N >
+template<class T>
BOOST_FORCEINLINE
-typename detail::addressof_addp< T[N] >::type addressof( T (&t)[N] )
+typename addressof_if<!addressof_is_constexpr<T>::value, T>::type
+addressof(T& o) BOOST_NOEXCEPT
{
- return &t;
+ return address_of<T>::get(addressof_ref<T>(o), 0);
}
-#endif
-
-// Borland doesn't like casting an array reference to a char reference
-// but these overloads work around the problem.
-#if defined( __BORLANDC__ ) && BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564))
-template<typename T,std::size_t N>
-BOOST_FORCEINLINE
-T (*addressof(T (&t)[N]))[N]
+template<class T>
+constexpr BOOST_FORCEINLINE
+typename addressof_if<addressof_is_constexpr<T>::value, T>::type
+addressof(T& o) BOOST_NOEXCEPT
{
- return reinterpret_cast<T(*)[N]>(&t);
+ return &o;
}
-template<typename T,std::size_t N>
-BOOST_FORCEINLINE
-const T (*addressof(const T (&t)[N]))[N]
+} /* detail */
+
+template<class T>
+constexpr BOOST_FORCEINLINE T*
+addressof(T& o) BOOST_NOEXCEPT
{
- return reinterpret_cast<const T(*)[N]>(&t);
+ return detail::addressof(o);
}
#endif
-} // namespace boost
+} /* boost */
+#endif
-#endif // BOOST_CORE_ADDRESSOF_HPP
+#endif
diff --git a/boost/core/demangle.hpp b/boost/core/demangle.hpp
index f13c26a7f4..dc714d806c 100644
--- a/boost/core/demangle.hpp
+++ b/boost/core/demangle.hpp
@@ -93,15 +93,10 @@ inline void demangle_free( char const * name ) BOOST_NOEXCEPT
inline std::string demangle( char const * name )
{
scoped_demangled_name demangled_name( name );
- char const * const p = demangled_name.get();
- if( p )
- {
- return p;
- }
- else
- {
- return name;
- }
+ char const * p = demangled_name.get();
+ if( !p )
+ p = name;
+ return p;
}
#else
diff --git a/boost/core/lightweight_test.hpp b/boost/core/lightweight_test.hpp
index d6db024250..b580dd2fa6 100644
--- a/boost/core/lightweight_test.hpp
+++ b/boost/core/lightweight_test.hpp
@@ -19,10 +19,12 @@
// http://www.boost.org/LICENSE_1_0.txt
//
+#include <iterator>
#include <boost/assert.hpp>
#include <boost/current_function.hpp>
#include <boost/core/no_exceptions_support.hpp>
#include <iostream>
+#include <cstring>
// IDE's like Visual Studio perform better if output goes to std::cout or
// some other stream, so allow user to configure output stream:
@@ -101,6 +103,16 @@ inline void throw_failed_impl(char const * excep, char const * file, int line, c
# pragma GCC diagnostic ignored "-Wsign-compare"
#endif
+// specialize test output for char pointers to avoid printing as cstring
+template <class T> inline const T& test_output_impl(const T& v) { return v; }
+inline const void* test_output_impl(const char* v) { return v; }
+inline const void* test_output_impl(const unsigned char* v) { return v; }
+inline const void* test_output_impl(const signed char* v) { return v; }
+inline const void* test_output_impl(char* v) { return v; }
+inline const void* test_output_impl(unsigned char* v) { return v; }
+inline const void* test_output_impl(signed char* v) { return v; }
+template<class T> inline const void* test_output_impl(T volatile* v) { return const_cast<T*>(v); }
+
template<class T, class U> inline void test_eq_impl( char const * expr1, char const * expr2,
char const * file, int line, char const * function, T const & t, U const & u )
{
@@ -113,7 +125,7 @@ template<class T, class U> inline void test_eq_impl( char const * expr1, char co
BOOST_LIGHTWEIGHT_TEST_OSTREAM
<< file << "(" << line << "): test '" << expr1 << " == " << expr2
<< "' failed in function '" << function << "': "
- << "'" << t << "' != '" << u << "'" << std::endl;
+ << "'" << test_output_impl(t) << "' != '" << test_output_impl(u) << "'" << std::endl;
++test_errors();
}
}
@@ -130,11 +142,182 @@ template<class T, class U> inline void test_ne_impl( char const * expr1, char co
BOOST_LIGHTWEIGHT_TEST_OSTREAM
<< file << "(" << line << "): test '" << expr1 << " != " << expr2
<< "' failed in function '" << function << "': "
+ << "'" << test_output_impl(t) << "' == '" << test_output_impl(u) << "'" << std::endl;
+ ++test_errors();
+ }
+}
+
+inline void test_cstr_eq_impl( char const * expr1, char const * expr2,
+ char const * file, int line, char const * function, char const * const t, char const * const u )
+{
+ if( std::strcmp(t, u) == 0 )
+ {
+ report_errors_remind();
+ }
+ else
+ {
+ BOOST_LIGHTWEIGHT_TEST_OSTREAM
+ << file << "(" << line << "): test '" << expr1 << " == " << expr2
+ << "' failed in function '" << function << "': "
+ << "'" << t << "' != '" << u << "'" << std::endl;
+ ++test_errors();
+ }
+}
+
+inline void test_cstr_ne_impl( char const * expr1, char const * expr2,
+ char const * file, int line, char const * function, char const * const t, char const * const u )
+{
+ if( std::strcmp(t, u) != 0 )
+ {
+ report_errors_remind();
+ }
+ else
+ {
+ BOOST_LIGHTWEIGHT_TEST_OSTREAM
+ << file << "(" << line << "): test '" << expr1 << " == " << expr2
+ << "' failed in function '" << function << "': "
<< "'" << t << "' == '" << u << "'" << std::endl;
++test_errors();
}
}
+template<class FormattedOutputFunction, class InputIterator1, class InputIterator2>
+void test_all_eq_impl(FormattedOutputFunction& output,
+ char const * file, int line, char const * function,
+ InputIterator1 first_begin, InputIterator1 first_end,
+ InputIterator2 second_begin, InputIterator2 second_end)
+{
+ InputIterator1 first_it = first_begin;
+ InputIterator2 second_it = second_begin;
+ typename std::iterator_traits<InputIterator1>::difference_type first_index = 0;
+ typename std::iterator_traits<InputIterator2>::difference_type second_index = 0;
+ std::size_t error_count = 0;
+ const std::size_t max_count = 8;
+ do
+ {
+ while ((first_it != first_end) && (second_it != second_end) && (*first_it == *second_it))
+ {
+ ++first_it;
+ ++second_it;
+ ++first_index;
+ ++second_index;
+ }
+ if ((first_it == first_end) || (second_it == second_end))
+ {
+ break; // do-while
+ }
+ if (error_count == 0)
+ {
+ output << file << "(" << line << "): Container contents differ in function '" << function << "':";
+ }
+ else if (error_count >= max_count)
+ {
+ output << " ...";
+ break;
+ }
+ output << " [" << first_index << "] '" << test_output_impl(*first_it) << "' != '" << test_output_impl(*second_it) << "'";
+ ++first_it;
+ ++second_it;
+ ++first_index;
+ ++second_index;
+ ++error_count;
+ } while (first_it != first_end);
+
+ first_index += std::distance(first_it, first_end);
+ second_index += std::distance(second_it, second_end);
+ if (first_index != second_index)
+ {
+ if (error_count == 0)
+ {
+ output << file << "(" << line << "): Container sizes differ in function '" << function << "': size(" << first_index << ") != size(" << second_index << ")";
+ }
+ else
+ {
+ output << " [*] size(" << first_index << ") != size(" << second_index << ")";
+ }
+ ++error_count;
+ }
+
+ if (error_count == 0)
+ {
+ boost::detail::report_errors_remind();
+ }
+ else
+ {
+ output << std::endl;
+ ++boost::detail::test_errors();
+ }
+}
+
+template<class FormattedOutputFunction, class InputIterator1, class InputIterator2, typename BinaryPredicate>
+void test_all_with_impl(FormattedOutputFunction& output,
+ char const * file, int line, char const * function,
+ InputIterator1 first_begin, InputIterator1 first_end,
+ InputIterator2 second_begin, InputIterator2 second_end,
+ BinaryPredicate predicate)
+{
+ InputIterator1 first_it = first_begin;
+ InputIterator2 second_it = second_begin;
+ typename std::iterator_traits<InputIterator1>::difference_type first_index = 0;
+ typename std::iterator_traits<InputIterator2>::difference_type second_index = 0;
+ std::size_t error_count = 0;
+ const std::size_t max_count = 8;
+ do
+ {
+ while ((first_it != first_end) && (second_it != second_end) && predicate(*first_it, *second_it))
+ {
+ ++first_it;
+ ++second_it;
+ ++first_index;
+ ++second_index;
+ }
+ if ((first_it == first_end) || (second_it == second_end))
+ {
+ break; // do-while
+ }
+ if (error_count == 0)
+ {
+ output << file << "(" << line << "): Container contents differ in function '" << function << "':";
+ }
+ else if (error_count >= max_count)
+ {
+ output << " ...";
+ break;
+ }
+ output << " [" << first_index << "]";
+ ++first_it;
+ ++second_it;
+ ++first_index;
+ ++second_index;
+ ++error_count;
+ } while (first_it != first_end);
+
+ first_index += std::distance(first_it, first_end);
+ second_index += std::distance(second_it, second_end);
+ if (first_index != second_index)
+ {
+ if (error_count == 0)
+ {
+ output << file << "(" << line << "): Container sizes differ in function '" << function << "': size(" << first_index << ") != size(" << second_index << ")";
+ }
+ else
+ {
+ output << " [*] size(" << first_index << ") != size(" << second_index << ")";
+ }
+ ++error_count;
+ }
+
+ if (error_count == 0)
+ {
+ report_errors_remind();
+ }
+ else
+ {
+ output << std::endl;
+ ++test_errors();
+ }
+}
+
#if defined(_MSC_VER)
# pragma warning(pop)
#elif defined(__clang__) && defined(__has_warning)
@@ -177,6 +360,12 @@ inline int report_errors()
#define BOOST_TEST_EQ(expr1,expr2) ( ::boost::detail::test_eq_impl(#expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2) )
#define BOOST_TEST_NE(expr1,expr2) ( ::boost::detail::test_ne_impl(#expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2) )
+#define BOOST_TEST_CSTR_EQ(expr1,expr2) ( ::boost::detail::test_cstr_eq_impl(#expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2) )
+#define BOOST_TEST_CSTR_NE(expr1,expr2) ( ::boost::detail::test_cstr_ne_impl(#expr1, #expr2, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, expr1, expr2) )
+
+#define BOOST_TEST_ALL_EQ(begin1, end1, begin2, end2) ( ::boost::detail::test_all_eq_impl(BOOST_LIGHTWEIGHT_TEST_OSTREAM, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, begin1, end1, begin2, end2) )
+#define BOOST_TEST_ALL_WITH(begin1, end1, begin2, end2, predicate) ( ::boost::detail::test_all_with_impl(BOOST_LIGHTWEIGHT_TEST_OSTREAM, __FILE__, __LINE__, BOOST_CURRENT_FUNCTION, begin1, end1, begin2, end2, predicate) )
+
#ifndef BOOST_NO_EXCEPTIONS
#define BOOST_TEST_THROWS( EXPR, EXCEP ) \
try { \