From 9f8dd573866a48938d53eab8eade1de41e62a6b1 Mon Sep 17 00:00:00 2001
From: Andrzej Krzemienski
Date: Thu, 1 Oct 2015 15:26:15 +0200
Subject: [PATCH 01/54] boost::none - simpler and works with MSVC
---
doc/21_ref_none.qbk | 8 ++++---
doc/html/index.html | 2 +-
doc/html/optional/reference.html | 16 ++++++++-----
include/boost/none.hpp | 12 +++++++---
include/boost/none_t.hpp | 18 ++++++++++++---
include/boost/optional/optional_io.hpp | 4 ++--
test/Jamfile.v2 | 1 +
.../optional_test_fail_none_io_without_io.cpp | 23 +++++++++++++++++++
8 files changed, 66 insertions(+), 18 deletions(-)
create mode 100644 test/optional_test_fail_none_io_without_io.cpp
diff --git a/doc/21_ref_none.qbk b/doc/21_ref_none.qbk
index e3b921e..011eff7 100644
--- a/doc/21_ref_none.qbk
+++ b/doc/21_ref_none.qbk
@@ -15,14 +15,16 @@
```
namespace boost {
-class none_t {};
+class none_t {/* see below */};
-extern const none_t none; // see below
+const none_t none (/* see below */);
} // namespace boost
```
-Variable `none` has external linkage, however it is not required to link with any library to obtain its definition. Only by including this header file, the definition becomes available, by means of using template instantiation.
+Class `none_t` is meant to serve as a tag for selecting appropriate overloads of from `optional`'s interface. It is an empty, trivially copyable class with disabled default constructor.
+
+Constant `none` is used to indicate an optional object that does not contain a value in initialization, assignment and relational operations of `optional`.
[endsect]
diff --git a/doc/html/index.html b/doc/html/index.html
index 2b0d9fd..833a9f6 100644
--- a/doc/html/index.html
+++ b/doc/html/index.html
@@ -146,7 +146,7 @@
-Last revised: July 08, 2015 at 21:39:55 GMT |
+Last revised: October 01, 2015 at 13:19:55 GMT |
|
diff --git a/doc/html/optional/reference.html b/doc/html/optional/reference.html
index 242e029..0cc575c 100644
--- a/doc/html/optional/reference.html
+++ b/doc/html/optional/reference.html
@@ -52,19 +52,23 @@
namespace boost {
-class none_t {};
+class none_t {/* see below */};
-extern const none_t none;
+const none_t none (/* see below */);
}
- Variable none
has external
- linkage, however it is not required to link with any library to obtain
- its definition. Only by including this header file, the definition becomes
- available, by means of using template instantiation.
+ Class none_t
is meant to
+ serve as a tag for selecting appropriate overloads of from optional
's interface. It is an empty,
+ trivially copyable class with disabled default constructor.
+
+
+ Constant none
is used to
+ indicate an optional object that does not contain a value in initialization,
+ assignment and relational operations of optional
.
diff --git a/include/boost/none.hpp b/include/boost/none.hpp
index 87a6c70..db744e5 100644
--- a/include/boost/none.hpp
+++ b/include/boost/none.hpp
@@ -22,8 +22,10 @@
namespace boost {
#ifdef BOOST_OPTIONAL_USE_OLD_DEFINITION_OF_NONE
+
none_t const none = (static_cast(0)) ;
-#else
+
+#elif defined BOOST_OPTIONAL_USE_SINGLETON_DEFINITION_OF_NONE
namespace detail { namespace optional_detail {
@@ -45,9 +47,13 @@ namespace {
const none_t& none = detail::optional_detail::none_instance::instance;
}
-#endif
+#else
+
+const none_t none ((none_t::init_tag()));
+
+#endif // older definitions
} // namespace boost
-#endif
+#endif // header guard
diff --git a/include/boost/none_t.hpp b/include/boost/none_t.hpp
index 13ce455..608cb0c 100644
--- a/include/boost/none_t.hpp
+++ b/include/boost/none_t.hpp
@@ -16,13 +16,25 @@
namespace boost {
#ifdef BOOST_OPTIONAL_USE_OLD_DEFINITION_OF_NONE
+
namespace detail { struct none_helper{}; }
typedef int detail::none_helper::*none_t ;
-#else
+
+#elif defined BOOST_OPTIONAL_USE_SINGLETON_DEFINITION_OF_NONE
+
class none_t {};
-#endif
+
+#else
+
+struct none_t
+{
+ struct init_tag{};
+ explicit none_t(init_tag){} // to prevent default constructor
+};
+
+#endif // old implementation workarounds
} // namespace boost
-#endif
+#endif // header guard
diff --git a/include/boost/optional/optional_io.hpp b/include/boost/optional/optional_io.hpp
index 16dbf95..ce81b68 100644
--- a/include/boost/optional/optional_io.hpp
+++ b/include/boost/optional/optional_io.hpp
@@ -15,7 +15,7 @@
#include
#include
-#include
+#include "boost/none.hpp"
#include "boost/optional/optional.hpp"
@@ -25,7 +25,7 @@ namespace boost
template
inline
std::basic_ostream&
-operator<<(std::basic_ostream& out, none_t const&)
+operator<<(std::basic_ostream& out, none_t)
{
if (out.good())
{
diff --git a/test/Jamfile.v2 b/test/Jamfile.v2
index ea9e81b..6b4e857 100644
--- a/test/Jamfile.v2
+++ b/test/Jamfile.v2
@@ -58,6 +58,7 @@ import testing ;
[ compile-fail optional_test_fail_explicit_convert_in_value_or.cpp ]
[ compile-fail optional_test_fail_explicit_convert_in_value_or_call.cpp ]
[ compile-fail optional_test_fail_io_without_io.cpp ]
+ [ compile-fail optional_test_fail_none_io_without_io.cpp ]
[ compile-fail optional_test_fail_convert_assign_of_enums.cpp ]
;
}
diff --git a/test/optional_test_fail_none_io_without_io.cpp b/test/optional_test_fail_none_io_without_io.cpp
new file mode 100644
index 0000000..7fa19a9
--- /dev/null
+++ b/test/optional_test_fail_none_io_without_io.cpp
@@ -0,0 +1,23 @@
+// Copyright (C) 2015, Andrzej Krzemienski.
+//
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/lib/optional for documentation.
+//
+// You are welcome to contact the author at:
+// akrzemi1@gmail.com
+
+#include
+#include "boost/none.hpp"
+// but no boost/optional/optional_io.hpp
+
+// THIS TEST SHOULD FAIL TO COMPILE
+// Unless one includes header boost/optional/optional_io.hpp, it should not be possible
+// to stream out boost::none.
+
+void test_streaming_out_none()
+{
+ std::cout << boost::none;
+}
\ No newline at end of file
From a46b0df3d1a8a7c19b739b704677283c81c8e064 Mon Sep 17 00:00:00 2001
From: Andrzej Krzemienski
Date: Sat, 3 Oct 2015 13:32:48 +0200
Subject: [PATCH 02/54] removed Boost.Test dependency
---
test/optional_test.cpp | 228 +++++++++++++++++-----------------
test/optional_test_common.cpp | 74 +++++------
2 files changed, 151 insertions(+), 151 deletions(-)
diff --git a/test/optional_test.cpp b/test/optional_test.cpp
index 3591867..017d4ff 100644
--- a/test/optional_test.cpp
+++ b/test/optional_test.cpp
@@ -30,7 +30,7 @@
#include "boost/none.hpp"
-#include "boost/test/minimal.hpp"
+#include "boost/core/lightweight_test.hpp"
#include "optional_test_common.cpp"
@@ -46,12 +46,12 @@ void test_implicit_construction ( optional opt, X const& v, X const& z )
void test_default_implicit_construction ( double, optional opt )
{
- BOOST_CHECK(!opt);
+ BOOST_TEST(!opt);
}
void test_default_implicit_construction ( X const&, optional opt )
{
- BOOST_CHECK(!opt);
+ BOOST_TEST(!opt);
}
//
@@ -188,65 +188,65 @@ void test_conditional_ctor_and_get_valur_or ( T const* )
check_value(o1,a,z);
T b = def0.get_value_or(z);
- BOOST_CHECK( b == z ) ;
+ BOOST_TEST( b == z ) ;
b = get_optional_value_or(def0,z);
- BOOST_CHECK( b == z ) ;
+ BOOST_TEST( b == z ) ;
b = o0.get_value_or(z);
- BOOST_CHECK( b == a ) ;
+ BOOST_TEST( b == a ) ;
b = get_optional_value_or(o0,z);
- BOOST_CHECK( b == a ) ;
+ BOOST_TEST( b == a ) ;
T const& crz = z ;
T& rz = z ;
T const& crzz = def0.get_value_or(crz);
- BOOST_CHECK( crzz == crz ) ;
+ BOOST_TEST( crzz == crz ) ;
T& rzz = def0.get_value_or(rz);
- BOOST_CHECK( rzz == rz ) ;
+ BOOST_TEST( rzz == rz ) ;
T const& crzzz = get_optional_value_or(cdef0,crz);
- BOOST_CHECK( crzzz == crz ) ;
+ BOOST_TEST( crzzz == crz ) ;
T& rzzz = get_optional_value_or(def0,rz);
- BOOST_CHECK( rzzz == rz ) ;
+ BOOST_TEST( rzzz == rz ) ;
T const& crb = o0.get_value_or(crz);
- BOOST_CHECK( crb == a ) ;
+ BOOST_TEST( crb == a ) ;
T& rb = o0.get_value_or(rz);
- BOOST_CHECK( rb == b ) ;
+ BOOST_TEST( rb == b ) ;
T const& crbb = get_optional_value_or(co0,crz);
- BOOST_CHECK( crbb == b ) ;
+ BOOST_TEST( crbb == b ) ;
T const& crbbb = get_optional_value_or(o0,crz);
- BOOST_CHECK( crbbb == b ) ;
+ BOOST_TEST( crbbb == b ) ;
T& rbb = get_optional_value_or(o0,rz);
- BOOST_CHECK( rbb == b ) ;
+ BOOST_TEST( rbb == b ) ;
T& ra = a ;
optional defref(false,ra);
- BOOST_CHECK(!defref);
+ BOOST_TEST(!defref);
optional ref(true,ra);
- BOOST_CHECK(!!ref);
+ BOOST_TEST(!!ref);
a = T(432);
- BOOST_CHECK( *ref == a ) ;
+ BOOST_TEST( *ref == a ) ;
T& r1 = defref.get_value_or(z);
- BOOST_CHECK( r1 == z ) ;
+ BOOST_TEST( r1 == z ) ;
T& r2 = ref.get_value_or(z);
- BOOST_CHECK( r2 == a ) ;
+ BOOST_TEST( r2 == a ) ;
}
//
@@ -262,18 +262,18 @@ void test_direct_value_manip( T const* )
optional const c_opt0(x) ;
optional opt0(x);
- BOOST_CHECK( c_opt0.get().V() == x.V() ) ;
- BOOST_CHECK( opt0.get().V() == x.V() ) ;
+ BOOST_TEST( c_opt0.get().V() == x.V() ) ;
+ BOOST_TEST( opt0.get().V() == x.V() ) ;
- BOOST_CHECK( c_opt0->V() == x.V() ) ;
- BOOST_CHECK( opt0->V() == x.V() ) ;
+ BOOST_TEST( c_opt0->V() == x.V() ) ;
+ BOOST_TEST( opt0->V() == x.V() ) ;
- BOOST_CHECK( (*c_opt0).V() == x.V() ) ;
- BOOST_CHECK( (* opt0).V() == x.V() ) ;
+ BOOST_TEST( (*c_opt0).V() == x.V() ) ;
+ BOOST_TEST( (* opt0).V() == x.V() ) ;
T y(4);
opt0 = y ;
- BOOST_CHECK( get(opt0).V() == y.V() ) ;
+ BOOST_TEST( get(opt0).V() == y.V() ) ;
}
//
@@ -295,7 +295,7 @@ void test_uninitialized_access( T const* )
passed = true ;
}
catch (...) {}
- BOOST_CHECK(!passed);
+ BOOST_TEST(!passed);
passed = false ;
try
@@ -306,7 +306,7 @@ void test_uninitialized_access( T const* )
passed = true ;
}
catch (...) {}
- BOOST_CHECK(!passed);
+ BOOST_TEST(!passed);
passed = false ;
try
@@ -318,7 +318,7 @@ void test_uninitialized_access( T const* )
passed = true ;
}
catch (...) {}
- BOOST_CHECK(!passed);
+ BOOST_TEST(!passed);
passed = false ;
try
@@ -329,7 +329,7 @@ void test_uninitialized_access( T const* )
passed = true ;
}
catch (...) {}
- BOOST_CHECK(!passed);
+ BOOST_TEST(!passed);
}
#if BOOST_WORKAROUND( BOOST_INTEL_CXX_VERSION, <= 700) // Intel C++ 7.0
@@ -374,7 +374,7 @@ void test_throwing_direct_init( T const* )
}
catch ( ... ){}
- BOOST_CHECK(!passed);
+ BOOST_TEST(!passed);
check_is_not_pending_copy( ARG(T) );
check_instance_count(count, ARG(T) );
@@ -410,7 +410,7 @@ void test_throwing_val_assign_on_uninitialized( T const* )
}
catch ( ... ) {}
- BOOST_CHECK(!passed);
+ BOOST_TEST(!passed);
check_is_not_pending_copy( ARG(T) );
check_instance_count(count, ARG(T) );
@@ -456,7 +456,7 @@ void test_throwing_val_assign_on_initialized( T const* )
}
catch ( ... ) {}
- BOOST_CHECK(!passed);
+ BOOST_TEST(!passed);
check_is_not_pending_assign( ARG(T) );
check_instance_count(count, ARG(T) );
@@ -495,7 +495,7 @@ void test_throwing_copy_initialization( T const* )
}
catch ( ... ) {}
- BOOST_CHECK(!passed);
+ BOOST_TEST(!passed);
check_is_not_pending_copy( ARG(T) );
check_instance_count(count, ARG(T) );
@@ -538,7 +538,7 @@ void test_throwing_assign_to_uninitialized( T const* )
}
catch ( ... ) {}
- BOOST_CHECK(!passed);
+ BOOST_TEST(!passed);
check_is_not_pending_copy( ARG(T) );
check_instance_count(count, ARG(T) );
@@ -581,7 +581,7 @@ void test_throwing_assign_to_initialized( T const* )
}
catch ( ... ) {}
- BOOST_CHECK(!passed);
+ BOOST_TEST(!passed);
// opt0 was left uninitialized
check_is_not_pending_assign( ARG(T) );
@@ -661,7 +661,7 @@ void test_throwing_swap( T const* )
}
catch ( ... ) {}
- BOOST_CHECK(!passed);
+ BOOST_TEST(!passed);
// optional's swap doesn't affect the initialized states of the arguments. Therefore,
// the following must hold:
@@ -692,7 +692,7 @@ void test_throwing_swap( T const* )
}
catch ( ... ) {}
- BOOST_CHECK(!passed);
+ BOOST_TEST(!passed);
check_uninitialized(opt0);
check_initialized(opt1);
@@ -720,69 +720,69 @@ void test_relops( T const* )
optional opt2(v2);
// Check identity
- BOOST_CHECK ( def0 == def0 ) ;
- BOOST_CHECK ( opt0 == opt0 ) ;
- BOOST_CHECK ( !(def0 != def0) ) ;
- BOOST_CHECK ( !(opt0 != opt0) ) ;
+ BOOST_TEST ( def0 == def0 ) ;
+ BOOST_TEST ( opt0 == opt0 ) ;
+ BOOST_TEST ( !(def0 != def0) ) ;
+ BOOST_TEST ( !(opt0 != opt0) ) ;
// Check when both are uininitalized.
- BOOST_CHECK ( def0 == def1 ) ; // both uninitialized compare equal
- BOOST_CHECK ( !(def0 < def1) ) ; // uninitialized is never less than uninitialized
- BOOST_CHECK ( !(def0 > def1) ) ; // uninitialized is never greater than uninitialized
- BOOST_CHECK ( !(def0 != def1) ) ;
- BOOST_CHECK ( def0 <= def1 ) ;
- BOOST_CHECK ( def0 >= def1 ) ;
+ BOOST_TEST ( def0 == def1 ) ; // both uninitialized compare equal
+ BOOST_TEST ( !(def0 < def1) ) ; // uninitialized is never less than uninitialized
+ BOOST_TEST ( !(def0 > def1) ) ; // uninitialized is never greater than uninitialized
+ BOOST_TEST ( !(def0 != def1) ) ;
+ BOOST_TEST ( def0 <= def1 ) ;
+ BOOST_TEST ( def0 >= def1 ) ;
// Check when only lhs is uninitialized.
- BOOST_CHECK ( def0 != opt0 ) ; // uninitialized is never equal to initialized
- BOOST_CHECK ( !(def0 == opt0) ) ;
- BOOST_CHECK ( def0 < opt0 ) ; // uninitialized is always less than initialized
- BOOST_CHECK ( !(def0 > opt0) ) ;
- BOOST_CHECK ( def0 <= opt0 ) ;
- BOOST_CHECK ( !(def0 >= opt0) ) ;
+ BOOST_TEST ( def0 != opt0 ) ; // uninitialized is never equal to initialized
+ BOOST_TEST ( !(def0 == opt0) ) ;
+ BOOST_TEST ( def0 < opt0 ) ; // uninitialized is always less than initialized
+ BOOST_TEST ( !(def0 > opt0) ) ;
+ BOOST_TEST ( def0 <= opt0 ) ;
+ BOOST_TEST ( !(def0 >= opt0) ) ;
// Check when only rhs is uninitialized.
- BOOST_CHECK ( opt0 != def0 ) ; // initialized is never equal to uninitialized
- BOOST_CHECK ( !(opt0 == def0) ) ;
- BOOST_CHECK ( !(opt0 < def0) ) ; // initialized is never less than uninitialized
- BOOST_CHECK ( opt0 > def0 ) ;
- BOOST_CHECK ( !(opt0 <= def0) ) ;
- BOOST_CHECK ( opt0 >= opt0 ) ;
+ BOOST_TEST ( opt0 != def0 ) ; // initialized is never equal to uninitialized
+ BOOST_TEST ( !(opt0 == def0) ) ;
+ BOOST_TEST ( !(opt0 < def0) ) ; // initialized is never less than uninitialized
+ BOOST_TEST ( opt0 > def0 ) ;
+ BOOST_TEST ( !(opt0 <= def0) ) ;
+ BOOST_TEST ( opt0 >= opt0 ) ;
// If both are initialized, values are compared
- BOOST_CHECK ( opt0 != opt1 ) ;
- BOOST_CHECK ( opt1 == opt2 ) ;
- BOOST_CHECK ( opt0 < opt1 ) ;
- BOOST_CHECK ( opt1 > opt0 ) ;
- BOOST_CHECK ( opt1 <= opt2 ) ;
- BOOST_CHECK ( opt1 >= opt0 ) ;
+ BOOST_TEST ( opt0 != opt1 ) ;
+ BOOST_TEST ( opt1 == opt2 ) ;
+ BOOST_TEST ( opt0 < opt1 ) ;
+ BOOST_TEST ( opt1 > opt0 ) ;
+ BOOST_TEST ( opt1 <= opt2 ) ;
+ BOOST_TEST ( opt1 >= opt0 ) ;
// Compare against a value directly
- BOOST_CHECK ( opt0 == v0 ) ;
- BOOST_CHECK ( opt0 != v1 ) ;
- BOOST_CHECK ( opt1 == v2 ) ;
- BOOST_CHECK ( opt0 < v1 ) ;
- BOOST_CHECK ( opt1 > v0 ) ;
- BOOST_CHECK ( opt1 <= v2 ) ;
- BOOST_CHECK ( opt1 >= v0 ) ;
- BOOST_CHECK ( v0 != opt1 ) ;
- BOOST_CHECK ( v1 == opt2 ) ;
- BOOST_CHECK ( v0 < opt1 ) ;
- BOOST_CHECK ( v1 > opt0 ) ;
- BOOST_CHECK ( v1 <= opt2 ) ;
- BOOST_CHECK ( v1 >= opt0 ) ;
- BOOST_CHECK ( def0 != v0 ) ;
- BOOST_CHECK ( !(def0 == v0) ) ;
- BOOST_CHECK ( def0 < v0 ) ;
- BOOST_CHECK ( !(def0 > v0) ) ;
- BOOST_CHECK ( def0 <= v0 ) ;
- BOOST_CHECK ( !(def0 >= v0) ) ;
- BOOST_CHECK ( v0 != def0 ) ;
- BOOST_CHECK ( !(v0 == def0) ) ;
- BOOST_CHECK ( !(v0 < def0) ) ;
- BOOST_CHECK ( v0 > def0 ) ;
- BOOST_CHECK ( !(v0 <= def0) ) ;
- BOOST_CHECK ( v0 >= opt0 ) ;
+ BOOST_TEST ( opt0 == v0 ) ;
+ BOOST_TEST ( opt0 != v1 ) ;
+ BOOST_TEST ( opt1 == v2 ) ;
+ BOOST_TEST ( opt0 < v1 ) ;
+ BOOST_TEST ( opt1 > v0 ) ;
+ BOOST_TEST ( opt1 <= v2 ) ;
+ BOOST_TEST ( opt1 >= v0 ) ;
+ BOOST_TEST ( v0 != opt1 ) ;
+ BOOST_TEST ( v1 == opt2 ) ;
+ BOOST_TEST ( v0 < opt1 ) ;
+ BOOST_TEST ( v1 > opt0 ) ;
+ BOOST_TEST ( v1 <= opt2 ) ;
+ BOOST_TEST ( v1 >= opt0 ) ;
+ BOOST_TEST ( def0 != v0 ) ;
+ BOOST_TEST ( !(def0 == v0) ) ;
+ BOOST_TEST ( def0 < v0 ) ;
+ BOOST_TEST ( !(def0 > v0) ) ;
+ BOOST_TEST ( def0 <= v0 ) ;
+ BOOST_TEST ( !(def0 >= v0) ) ;
+ BOOST_TEST ( v0 != def0 ) ;
+ BOOST_TEST ( !(v0 == def0) ) ;
+ BOOST_TEST ( !(v0 < def0) ) ;
+ BOOST_TEST ( v0 > def0 ) ;
+ BOOST_TEST ( !(v0 <= def0) ) ;
+ BOOST_TEST ( v0 >= opt0 ) ;
}
template
@@ -796,16 +796,16 @@ void test_none( T const* )
optional def1(none) ;
optional non_def( T(1234) ) ;
- BOOST_CHECK ( def0 == none ) ;
- BOOST_CHECK ( non_def != none ) ;
- BOOST_CHECK ( !def1 ) ;
- BOOST_CHECK ( !(non_def < none) ) ;
- BOOST_CHECK ( non_def > none ) ;
- BOOST_CHECK ( !(non_def <= none) ) ;
- BOOST_CHECK ( non_def >= none ) ;
+ BOOST_TEST ( def0 == none ) ;
+ BOOST_TEST ( non_def != none ) ;
+ BOOST_TEST ( !def1 ) ;
+ BOOST_TEST ( !(non_def < none) ) ;
+ BOOST_TEST ( non_def > none ) ;
+ BOOST_TEST ( !(non_def <= none) ) ;
+ BOOST_TEST ( non_def >= none ) ;
non_def = none ;
- BOOST_CHECK ( !non_def ) ;
+ BOOST_TEST ( !non_def ) ;
test_default_implicit_construction(T(1),none);
}
@@ -820,12 +820,12 @@ void test_arrow( T const* )
optional oa(a) ;
optional const coa(a) ;
- BOOST_CHECK ( coa->V() == 1234 ) ;
+ BOOST_TEST ( coa->V() == 1234 ) ;
oa->V() = 4321 ;
- BOOST_CHECK ( a.V() = 1234 ) ;
- BOOST_CHECK ( (*oa).V() = 4321 ) ;
+ BOOST_TEST ( a.V() = 1234 ) ;
+ BOOST_TEST ( (*oa).V() = 4321 ) ;
}
void test_with_builtin_types()
@@ -869,7 +869,7 @@ void test_with_class_type()
test_relops( ARG(X) ) ;
test_none( ARG(X) ) ;
test_arrow( ARG(X) ) ;
- BOOST_CHECK ( X::count == 0 ) ;
+ BOOST_TEST ( X::count == 0 ) ;
}
int eat ( bool ) { return 1 ; }
@@ -888,7 +888,7 @@ void test_no_implicit_conversions_impl( T const& )
TRACE( std::endl << BOOST_CURRENT_FUNCTION );
optional def ;
- BOOST_CHECK ( eat(def) == 0 ) ;
+ BOOST_TEST ( eat(def) == 0 ) ;
}
void test_no_implicit_conversions()
@@ -908,7 +908,7 @@ void test_no_implicit_conversions()
// Test for support for classes with overridden operator&
-class CustomAddressOfClass
+class CustomAddressOfClass
{
int n;
@@ -923,18 +923,18 @@ public:
void test_custom_addressof_operator()
{
boost::optional< CustomAddressOfClass > o1(CustomAddressOfClass(10));
- BOOST_CHECK(!!o1);
- BOOST_CHECK(o1.get() == CustomAddressOfClass(10));
+ BOOST_TEST(!!o1);
+ BOOST_TEST(o1.get() == CustomAddressOfClass(10));
o1 = CustomAddressOfClass(20);
- BOOST_CHECK(!!o1);
- BOOST_CHECK(o1.get() == CustomAddressOfClass(20));
+ BOOST_TEST(!!o1);
+ BOOST_TEST(o1.get() == CustomAddressOfClass(20));
o1 = boost::none;
- BOOST_CHECK(!o1);
+ BOOST_TEST(!o1);
}
-int test_main( int, char* [] )
+int main()
{
try
{
@@ -948,7 +948,7 @@ int test_main( int, char* [] )
BOOST_ERROR("Unexpected Exception caught!");
}
- return 0;
+ return boost::report_errors();
}
diff --git a/test/optional_test_common.cpp b/test/optional_test_common.cpp
index a527bd7..ff197bd 100644
--- a/test/optional_test_common.cpp
+++ b/test/optional_test_common.cpp
@@ -159,13 +159,13 @@ inline void set_throw_on_copy ( X const* x ) { X::throw_on_copy = true
inline void set_throw_on_assign ( X const* x ) { X::throw_on_assign = true ; }
inline void reset_throw_on_copy ( X const* x ) { X::throw_on_copy = false ; }
inline void reset_throw_on_assign ( X const* x ) { X::throw_on_assign = false ; }
-inline void check_is_pending_copy ( X const* x ) { BOOST_CHECK( X::pending_copy ) ; }
-inline void check_is_pending_dtor ( X const* x ) { BOOST_CHECK( X::pending_dtor ) ; }
-inline void check_is_pending_assign ( X const* x ) { BOOST_CHECK( X::pending_assign ) ; }
-inline void check_is_not_pending_copy ( X const* x ) { BOOST_CHECK( !X::pending_copy ) ; }
-inline void check_is_not_pending_dtor ( X const* x ) { BOOST_CHECK( !X::pending_dtor ) ; }
-inline void check_is_not_pending_assign( X const* x ) { BOOST_CHECK( !X::pending_assign ) ; }
-inline void check_instance_count ( int c, X const* x ) { BOOST_CHECK( X::count == c ) ; }
+inline void check_is_pending_copy ( X const* x ) { BOOST_TEST( X::pending_copy ) ; }
+inline void check_is_pending_dtor ( X const* x ) { BOOST_TEST( X::pending_dtor ) ; }
+inline void check_is_pending_assign ( X const* x ) { BOOST_TEST( X::pending_assign ) ; }
+inline void check_is_not_pending_copy ( X const* x ) { BOOST_TEST( !X::pending_copy ) ; }
+inline void check_is_not_pending_dtor ( X const* x ) { BOOST_TEST( !X::pending_dtor ) ; }
+inline void check_is_not_pending_assign( X const* x ) { BOOST_TEST( !X::pending_assign ) ; }
+inline void check_instance_count ( int c, X const* x ) { BOOST_TEST( X::count == c ) ; }
inline int get_instance_count ( X const* x ) { return X::count ; }
inline void set_pending_copy (...) {}
@@ -189,21 +189,21 @@ template
inline void check_uninitialized_const ( optional const& opt )
{
#ifndef BOOST_OPTIONAL_NO_NULL_COMPARE
- BOOST_CHECK( opt == 0 ) ;
+ BOOST_TEST( opt == 0 ) ;
#endif
- BOOST_CHECK( !opt ) ;
- BOOST_CHECK( !get_pointer(opt) ) ;
- BOOST_CHECK( !opt.get_ptr() ) ;
+ BOOST_TEST( !opt ) ;
+ BOOST_TEST( !get_pointer(opt) ) ;
+ BOOST_TEST( !opt.get_ptr() ) ;
}
template
inline void check_uninitialized ( optional& opt )
{
#ifndef BOOST_OPTIONAL_NO_NULL_COMPARE
- BOOST_CHECK( opt == 0 ) ;
+ BOOST_TEST( opt == 0 ) ;
#endif
- BOOST_CHECK( !opt ) ;
- BOOST_CHECK( !get_pointer(opt) ) ;
- BOOST_CHECK( !opt.get_ptr() ) ;
+ BOOST_TEST( !opt ) ;
+ BOOST_TEST( !get_pointer(opt) ) ;
+ BOOST_TEST( !opt.get_ptr() ) ;
check_uninitialized_const(opt);
}
@@ -211,29 +211,29 @@ inline void check_uninitialized ( optional& opt )
template
inline void check_initialized_const ( optional const& opt )
{
- BOOST_CHECK( opt ) ;
+ BOOST_TEST( opt ) ;
#ifndef BOOST_OPTIONAL_NO_NULL_COMPARE
- BOOST_CHECK( opt != 0 ) ;
+ BOOST_TEST( opt != 0 ) ;
#endif
- BOOST_CHECK ( !!opt ) ;
- BOOST_CHECK ( get_pointer(opt) ) ;
- BOOST_CHECK ( opt.get_ptr() ) ;
+ BOOST_TEST ( !!opt ) ;
+ BOOST_TEST ( get_pointer(opt) ) ;
+ BOOST_TEST ( opt.get_ptr() ) ;
}
template
inline void check_initialized ( optional& opt )
{
- BOOST_CHECK( opt ) ;
+ BOOST_TEST( opt ) ;
#ifndef BOOST_OPTIONAL_NO_NULL_COMPARE
- BOOST_CHECK( opt != 0 ) ;
+ BOOST_TEST( opt != 0 ) ;
#endif
- BOOST_CHECK ( !!opt ) ;
- BOOST_CHECK ( get_pointer(opt) ) ;
- BOOST_CHECK ( opt.get_ptr() ) ;
+ BOOST_TEST ( !!opt ) ;
+ BOOST_TEST ( get_pointer(opt) ) ;
+ BOOST_TEST ( opt.get_ptr() ) ;
check_initialized_const(opt);
}
@@ -241,12 +241,12 @@ inline void check_initialized ( optional& opt )
template
inline void check_value_const ( optional const& opt, T const& v, T const& z )
{
- BOOST_CHECK( *opt == v ) ;
- BOOST_CHECK( *opt != z ) ;
- BOOST_CHECK( opt.get() == v ) ;
- BOOST_CHECK( opt.get() != z ) ;
- BOOST_CHECK( (*(opt.operator->()) == v) ) ;
- BOOST_CHECK( *get_pointer(opt) == v ) ;
+ BOOST_TEST( *opt == v ) ;
+ BOOST_TEST( *opt != z ) ;
+ BOOST_TEST( opt.get() == v ) ;
+ BOOST_TEST( opt.get() != z ) ;
+ BOOST_TEST( (*(opt.operator->()) == v) ) ;
+ BOOST_TEST( *get_pointer(opt) == v ) ;
}
template
@@ -258,12 +258,12 @@ inline void check_value ( optional& opt, T const& v, T const& z )
reset_throw_on_copy( ARG(T) ) ;
#endif
- BOOST_CHECK( *opt == v ) ;
- BOOST_CHECK( *opt != z ) ;
- BOOST_CHECK( opt.get() == v ) ;
- BOOST_CHECK( opt.get() != z ) ;
- BOOST_CHECK( (*(opt.operator->()) == v) ) ;
- BOOST_CHECK( *get_pointer(opt) == v ) ;
+ BOOST_TEST( *opt == v ) ;
+ BOOST_TEST( *opt != z ) ;
+ BOOST_TEST( opt.get() == v ) ;
+ BOOST_TEST( opt.get() != z ) ;
+ BOOST_TEST( (*(opt.operator->()) == v) ) ;
+ BOOST_TEST( *get_pointer(opt) == v ) ;
check_value_const(opt,v,z);
}
From cf4b2e8b16d158146e7ad2fc36aa755bb953dc55 Mon Sep 17 00:00:00 2001
From: Andrzej Krzemienski
Date: Mon, 5 Oct 2015 16:54:05 +0200
Subject: [PATCH 03/54] specialization for optional ref - preliminary
---
doc/91_relnotes.qbk | 5 +
doc/html/boost_optional/relnotes.html | 23 +-
doc/html/index.html | 2 +-
.../boost/optional/detail/optional_config.hpp | 55 +++
.../detail/optional_reference_spec.hpp | 164 +++++++++
.../boost/optional/detail/optional_relops.hpp | 195 ++++++++++
.../boost/optional/detail/optional_swap.hpp | 117 ++++++
include/boost/optional/optional.hpp | 339 +-----------------
8 files changed, 571 insertions(+), 329 deletions(-)
create mode 100644 include/boost/optional/detail/optional_config.hpp
create mode 100644 include/boost/optional/detail/optional_reference_spec.hpp
create mode 100644 include/boost/optional/detail/optional_relops.hpp
create mode 100644 include/boost/optional/detail/optional_swap.hpp
diff --git a/doc/91_relnotes.qbk b/doc/91_relnotes.qbk
index eb2b310..297a360 100644
--- a/doc/91_relnotes.qbk
+++ b/doc/91_relnotes.qbk
@@ -11,6 +11,11 @@
[section:relnotes Release Notes]
+[heading Boost Release X.XX]
+
+* Changed the implementation of `boost::none`: now it is a constant with internal linkage. This addresses [@https://svn.boost.org/trac/boost/ticket/11203 Trac #11203].
+* Now `boost::optional` is specialized for reference parameters. This way the `sizeof` of optional reference is that of a pointer, and a number of bugs is avoided.
+
[heading Boost Release 1.59]
* For C++03 compilers, added 0-argument overload for member function `emplace()`, and therewith removed the dependency on ``.
diff --git a/doc/html/boost_optional/relnotes.html b/doc/html/boost_optional/relnotes.html
index 445eaa8..bac08cc 100644
--- a/doc/html/boost_optional/relnotes.html
+++ b/doc/html/boost_optional/relnotes.html
@@ -28,6 +28,23 @@
+
+-
+ Changed the implementation of
boost::none
:
+ now it is a constant with internal linkage. This addresses Trac
+ #11203.
+
+-
+ Now
boost::optional
is specialized for reference
+ parameters. This way the sizeof
+ of optional reference is that of a pointer, and a number of bugs is avoided.
+
+
+
@@ -36,7 +53,7 @@
and therewith removed the dependency on <boost/utility/in_place_factory.hpp>
.
@@ -72,7 +89,7 @@
@@ -82,7 +99,7 @@
to fix C++03 compile error on logic_error("...")
".
diff --git a/doc/html/index.html b/doc/html/index.html
index 833a9f6..558d7e2 100644
--- a/doc/html/index.html
+++ b/doc/html/index.html
@@ -146,7 +146,7 @@
-Last revised: October 01, 2015 at 13:19:55 GMT |
+Last revised: October 05, 2015 at 14:34:49 GMT |
|
diff --git a/include/boost/optional/detail/optional_config.hpp b/include/boost/optional/detail/optional_config.hpp
new file mode 100644
index 0000000..c069c0d
--- /dev/null
+++ b/include/boost/optional/detail/optional_config.hpp
@@ -0,0 +1,55 @@
+// Copyright (C) 2003, 2008 Fernando Luis Cacciola Carballal.
+// Copyright (C) 2015 Andrzej Krzemienski.
+//
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/optional for documentation.
+//
+// You are welcome to contact the author at:
+// akrzemi1@gmail.com
+
+#ifndef BOOST_OPTIONAL_DETAIL_OPTIONAL_CONFIG_AJK_28JAN2015_HPP
+#define BOOST_OPTIONAL_DETAIL_OPTIONAL_CONFIG_AJK_28JAN2015_HPP
+
+#include
+#include
+
+#if (defined BOOST_NO_CXX11_RVALUE_REFERENCES) || (defined BOOST_OPTIONAL_CONFIG_NO_RVALUE_REFERENCES)
+# define BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
+#endif
+
+#if BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION,<=700)
+// AFAICT only Intel 7 correctly resolves the overload set
+// that includes the in-place factory taking functions,
+// so for the other icc versions, in-place factory support
+// is disabled
+# define BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
+#endif
+
+#if BOOST_WORKAROUND(__BORLANDC__, <= 0x551)
+// BCB (5.5.1) cannot parse the nested template struct in an inplace factory.
+# define BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
+#endif
+
+#if !defined(BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT) \
+ && defined BOOST_BCB_PARTIAL_SPECIALIZATION_BUG
+// BCB (up to 5.64) has the following bug:
+// If there is a member function/operator template of the form
+// template mfunc( Expr expr ) ;
+// some calls are resolved to this even if there are other better matches.
+// The effect of this bug is that calls to converting ctors and assignments
+// are incorrectly sink to this general catch-all member function template as shown above.
+# define BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION
+#endif
+
+#if defined(__GNUC__) && !defined(__INTEL_COMPILER)
+// GCC since 3.3 has may_alias attribute that helps to alleviate optimizer issues with
+// regard to violation of the strict aliasing rules. The optional< T > storage type is marked
+// with this attribute in order to let the compiler know that it will alias objects of type T
+// and silence compilation warnings.
+# define BOOST_OPTIONAL_DETAIL_USE_ATTRIBUTE_MAY_ALIAS
+#endif
+
+#endif // header guard
diff --git a/include/boost/optional/detail/optional_reference_spec.hpp b/include/boost/optional/detail/optional_reference_spec.hpp
new file mode 100644
index 0000000..5a76a68
--- /dev/null
+++ b/include/boost/optional/detail/optional_reference_spec.hpp
@@ -0,0 +1,164 @@
+// Copyright (C) 2015 Andrzej Krzemienski.
+//
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/optional for documentation.
+//
+// You are welcome to contact the author at:
+// akrzemi1@gmail.com
+
+#ifndef BOOST_OPTIONAL_DETAIL_OPTIONAL_REFERENCE_SPEC_AJK_03OCT2015_HPP
+#define BOOST_OPTIONAL_DETAIL_OPTIONAL_REFERENCE_SPEC_AJK_03OCT2015_HPP
+
+# if 1
+
+namespace boost {
+
+namespace detail {
+
+template
+void prevent_binding_rvalue()
+{
+#ifndef BOOST_OPTIONAL_CONFIG_ALLOW_BINDING_TO_RVALUES
+ BOOST_STATIC_ASSERT_MSG(boost::is_lvalue_reference::value,
+ "binding rvalue references to optional lvalue references is disallowed");
+#endif
+}
+
+template
+typename boost::remove_reference::type& forward_reference(T&& r)
+{
+ BOOST_STATIC_ASSERT_MSG(boost::is_lvalue_reference::value,
+ "binding rvalue references to optional lvalue references is disallowed");
+ return boost::forward(r);
+}
+
+template
+struct is_optional_
+{
+ static const bool value = false;
+};
+
+template
+struct is_optional_<::boost::optional>
+{
+ static const bool value = true;
+};
+
+template
+struct is_no_optional
+{
+ static const bool value = !is_optional_::type>::value;
+};
+
+} // namespace detail
+
+template
+class optional : public optional_detail::optional_tag
+{
+ T* ptr_;
+
+public:
+ typedef T& value_type;
+ typedef T& reference_type;
+ typedef T& reference_const_type;
+ typedef T* pointer_type;
+ typedef T* pointer_const_type;
+
+ optional() BOOST_NOEXCEPT : ptr_() {}
+ optional(none_t) BOOST_NOEXCEPT : ptr_() {}
+
+ template
+ explicit optional(const optional& rhs) BOOST_NOEXCEPT : ptr_(rhs.ptr_) {}
+ optional(const optional& rhs) BOOST_NOEXCEPT : ptr_(rhs.ptr_) {}
+
+
+ optional& operator=(const optional& rhs) BOOST_NOEXCEPT { ptr_ = rhs.ptr_; return *this; }
+ template
+ optional& operator=(const optional& rhs) BOOST_NOEXCEPT { ptr_ = rhs.ptr_; return *this; }
+ optional& operator=(none_t) BOOST_NOEXCEPT { ptr_ = 0; return *this; }
+
+
+ void swap(optional& rhs) BOOST_NOEXCEPT { std::swap(ptr_, rhs.ptr_); }
+ T& get() const { BOOST_ASSERT(ptr_); return *ptr_; }
+
+ T* get_ptr() const BOOST_NOEXCEPT { return ptr_; }
+ T* operator->() const { BOOST_ASSERT(ptr_); return ptr_; }
+ T& operator*() const { BOOST_ASSERT(ptr_); return *ptr_; }
+ T& value() const { return ptr_ ? *ptr_ : (throw_exception(bad_optional_access()), *ptr_); }
+
+
+ template
+ T& value_or_eval(F f) const { return ptr_ ? *ptr_ : detail::forward_reference(f()); }
+
+ bool operator!() const BOOST_NOEXCEPT { return ptr_ == 0; }
+ BOOST_EXPLICIT_OPERATOR_BOOL_NOEXCEPT()
+
+ void reset() BOOST_NOEXCEPT { ptr_ = 0; }
+
+ bool is_initialized() const BOOST_NOEXCEPT { return ptr_ != 0; }
+
+#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
+
+ template
+ optional(R&& r, BOOST_DEDUCED_TYPENAME boost::enable_if >::type* = 0) BOOST_NOEXCEPT
+ : ptr_(boost::addressof(r)) { detail::prevent_binding_rvalue(); }
+
+ template
+ optional(bool cond, R&& r, BOOST_DEDUCED_TYPENAME boost::enable_if >::type* = 0) BOOST_NOEXCEPT
+ : ptr_(cond ? boost::addressof(r) : 0) { detail::prevent_binding_rvalue(); }
+
+ template
+ BOOST_DEDUCED_TYPENAME boost::enable_if, optional&>::type
+ operator=(R&& r) BOOST_NOEXCEPT { detail::prevent_binding_rvalue(); ptr_ = boost::addressof(r); return *this; }
+
+ template
+ void emplace(R&& r, BOOST_DEDUCED_TYPENAME boost::enable_if >::type* = 0) BOOST_NOEXCEPT
+ { detail::prevent_binding_rvalue(); ptr_ = boost::addressof(r); }
+
+ template
+ T& get_value_or(R&& r, BOOST_DEDUCED_TYPENAME boost::enable_if >::type* = 0) const BOOST_NOEXCEPT
+ { detail::prevent_binding_rvalue(); return ptr_ ? *ptr_ : r; }
+
+ template
+ T& value_or(R&& r, BOOST_DEDUCED_TYPENAME boost::enable_if >::type* = 0) const BOOST_NOEXCEPT
+ { detail::prevent_binding_rvalue(); return ptr_ ? *ptr_ : r; }
+
+ template
+ void reset(R&& r, BOOST_DEDUCED_TYPENAME boost::enable_if >::type* = 0) BOOST_NOEXCEPT
+ { detail::prevent_binding_rvalue(); ptr_ = boost::addressof(r); }
+
+#else // BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
+
+ template
+ optional(const U& v) BOOST_NOEXCEPT : ptr_(boost::addressof(v)) { }
+
+ template
+ optional(bool cond, const U& v) BOOST_NOEXCEPT : ptr_(cond ? boost::addressof(v) : 0) {}
+
+ template
+ optional operator=(const U& v) BOOST_NOEXCEPT { ptr_ = boost::addressof(v); return *this; }
+
+ template
+ void emplace(const U& v) BOOST_NOEXCEPT { ptr_ = boost::addressof(v); }
+
+ template
+ T& get_value_or(const U& v) const BOOST_NOEXCEPT { return ptr_ ? *ptr_ : v; }
+
+ template
+ T& value_or(const U& v) const BOOST_NOEXCEPT { return ptr_ ? *ptr_ : v; }
+
+ template
+ void reset(const U& v) BOOST_NOEXCEPT { ptr_ = boost::addressof(v); }
+
+#endif // BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
+};
+
+// TODO: what if no rvalue refs
+} // namespace boost
+
+#endif // 0
+
+#endif // header guard
diff --git a/include/boost/optional/detail/optional_relops.hpp b/include/boost/optional/detail/optional_relops.hpp
new file mode 100644
index 0000000..f3ebae0
--- /dev/null
+++ b/include/boost/optional/detail/optional_relops.hpp
@@ -0,0 +1,195 @@
+// Copyright (C) 2003, 2008 Fernando Luis Cacciola Carballal.
+// Copyright (C) 2015 Andrzej Krzemienski.
+//
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/optional for documentation.
+//
+// You are welcome to contact the author at:
+// akrzemi1@gmail.com
+
+#ifndef BOOST_OPTIONAL_DETAIL_OPTIONAL_RELOPS_AJK_03OCT2015_HPP
+#define BOOST_OPTIONAL_DETAIL_OPTIONAL_RELOPS_AJK_03OCT2015_HPP
+
+namespace boost {
+
+// optional's relational operators ( ==, !=, <, >, <=, >= ) have deep-semantics (compare values).
+// WARNING: This is UNLIKE pointers. Use equal_pointees()/less_pointess() in generic code instead.
+
+
+//
+// optional vs optional cases
+//
+
+template
+inline
+bool operator == ( optional const& x, optional const& y )
+{ return equal_pointees(x,y); }
+
+template
+inline
+bool operator < ( optional const& x, optional const& y )
+{ return less_pointees(x,y); }
+
+template
+inline
+bool operator != ( optional const& x, optional const& y )
+{ return !( x == y ) ; }
+
+template
+inline
+bool operator > ( optional const& x, optional const& y )
+{ return y < x ; }
+
+template
+inline
+bool operator <= ( optional const& x, optional const& y )
+{ return !( y < x ) ; }
+
+template
+inline
+bool operator >= ( optional const& x, optional const& y )
+{ return !( x < y ) ; }
+
+
+//
+// optional vs T cases
+//
+template
+inline
+bool operator == ( optional const& x, T const& y )
+{ return equal_pointees(x, optional(y)); }
+
+template
+inline
+bool operator < ( optional const& x, T const& y )
+{ return less_pointees(x, optional(y)); }
+
+template
+inline
+bool operator != ( optional const& x, T const& y )
+{ return !( x == y ) ; }
+
+template
+inline
+bool operator > ( optional const& x, T const& y )
+{ return y < x ; }
+
+template
+inline
+bool operator <= ( optional const& x, T const& y )
+{ return !( y < x ) ; }
+
+template
+inline
+bool operator >= ( optional const& x, T const& y )
+{ return !( x < y ) ; }
+
+//
+// T vs optional cases
+//
+
+template
+inline
+bool operator == ( T const& x, optional const& y )
+{ return equal_pointees( optional(x), y ); }
+
+template
+inline
+bool operator < ( T const& x, optional const& y )
+{ return less_pointees( optional(x), y ); }
+
+template
+inline
+bool operator != ( T const& x, optional const& y )
+{ return !( x == y ) ; }
+
+template
+inline
+bool operator > ( T const& x, optional const& y )
+{ return y < x ; }
+
+template
+inline
+bool operator <= ( T const& x, optional const& y )
+{ return !( y < x ) ; }
+
+template
+inline
+bool operator >= ( T const& x, optional const& y )
+{ return !( x < y ) ; }
+
+
+//
+// optional vs none cases
+//
+
+template
+inline
+bool operator == ( optional const& x, none_t ) BOOST_NOEXCEPT
+{ return !x; }
+
+template
+inline
+bool operator < ( optional const& x, none_t )
+{ return less_pointees(x,optional() ); }
+
+template
+inline
+bool operator != ( optional const& x, none_t ) BOOST_NOEXCEPT
+{ return bool(x); }
+
+template
+inline
+bool operator > ( optional const& x, none_t y )
+{ return y < x ; }
+
+template
+inline
+bool operator <= ( optional const& x, none_t y )
+{ return !( y < x ) ; }
+
+template
+inline
+bool operator >= ( optional const& x, none_t y )
+{ return !( x < y ) ; }
+
+//
+// none vs optional cases
+//
+
+template
+inline
+bool operator == ( none_t , optional const& y ) BOOST_NOEXCEPT
+{ return !y; }
+
+template
+inline
+bool operator < ( none_t , optional const& y )
+{ return less_pointees(optional() ,y); }
+
+template
+inline
+bool operator != ( none_t, optional const& y ) BOOST_NOEXCEPT
+{ return bool(y); }
+
+template
+inline
+bool operator > ( none_t x, optional const& y )
+{ return y < x ; }
+
+template
+inline
+bool operator <= ( none_t x, optional const& y )
+{ return !( y < x ) ; }
+
+template
+inline
+bool operator >= ( none_t x, optional const& y )
+{ return !( x < y ) ; }
+
+} // namespace boost
+
+#endif // header guard
\ No newline at end of file
diff --git a/include/boost/optional/detail/optional_swap.hpp b/include/boost/optional/detail/optional_swap.hpp
new file mode 100644
index 0000000..2a7059e
--- /dev/null
+++ b/include/boost/optional/detail/optional_swap.hpp
@@ -0,0 +1,117 @@
+// Copyright (C) 2003, 2008 Fernando Luis Cacciola Carballal.
+// Copyright (C) 2015 Andrzej Krzemienski.
+//
+// Use, modification, and distribution is subject to the Boost Software
+// License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
+// http://www.boost.org/LICENSE_1_0.txt)
+//
+// See http://www.boost.org/libs/optional for documentation.
+//
+// You are welcome to contact the author at:
+// akrzemi1@gmail.com
+
+#ifndef BOOST_OPTIONAL_DETAIL_OPTIONAL_SWAP_AJK_28JAN2015_HPP
+#define BOOST_OPTIONAL_DETAIL_OPTIONAL_SWAP_AJK_28JAN2015_HPP
+
+#include
+#include
+
+namespace boost {
+
+namespace optional_detail {
+
+template struct swap_selector;
+
+template <>
+struct swap_selector
+{
+ template
+ static void optional_swap ( optional& x, optional& y )
+ {
+ const bool hasX = !!x;
+ const bool hasY = !!y;
+
+ if ( !hasX && !hasY )
+ return;
+
+ if( !hasX )
+ x.emplace();
+ else if ( !hasY )
+ y.emplace();
+
+ // Boost.Utility.Swap will take care of ADL and workarounds for broken compilers
+ boost::swap(x.get(), y.get());
+
+ if( !hasX )
+ y = boost::none ;
+ else if( !hasY )
+ x = boost::none ;
+ }
+};
+
+#ifdef BOOST_OPTIONAL_DETAIL_MOVE
+# undef BOOST_OPTIONAL_DETAIL_MOVE
+#endif
+
+#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
+# define BOOST_OPTIONAL_DETAIL_MOVE(EXPR_) boost::move(EXPR_)
+#else
+# define BOOST_OPTIONAL_DETAIL_MOVE(EXPR_) EXPR_
+#endif
+
+template <>
+struct swap_selector
+{
+ template
+ static void optional_swap ( optional& x, optional& y )
+ //BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible::value && BOOST_NOEXCEPT_EXPR(boost::swap(*x, *y)))
+ {
+ if (x)
+ {
+ if (y)
+ {
+ boost::swap(*x, *y);
+ }
+ else
+ {
+ y = BOOST_OPTIONAL_DETAIL_MOVE(*x);
+ x = boost::none;
+ }
+ }
+ else
+ {
+ if (y)
+ {
+ x = BOOST_OPTIONAL_DETAIL_MOVE(*y);
+ y = boost::none;
+ }
+ }
+ }
+};
+
+} // namespace optional_detail
+
+#if (!defined BOOST_NO_CXX11_RVALUE_REFERENCES) && (!defined BOOST_CONFIG_RESTORE_OBSOLETE_SWAP_IMPLEMENTATION)
+
+template
+struct optional_swap_should_use_default_constructor : boost::false_type {} ;
+
+#else
+
+template
+struct optional_swap_should_use_default_constructor : has_nothrow_default_constructor {} ;
+
+#endif
+
+template
+inline void swap ( optional& x, optional& y )
+//BOOST_NOEXCEPT_IF(::boost::is_nothrow_move_constructible::value && BOOST_NOEXCEPT_EXPR(boost::swap(*x, *y)))
+{
+ optional_detail::swap_selector::value>::optional_swap(x, y);
+}
+
+} // namespace boost
+
+#undef BOOST_OPTIONAL_DETAIL_MOVE
+
+#endif // header guard
diff --git a/include/boost/optional/optional.hpp b/include/boost/optional/optional.hpp
index 9def94e..9cdc7ea 100644
--- a/include/boost/optional/optional.hpp
+++ b/include/boost/optional/optional.hpp
@@ -20,7 +20,6 @@
#include
#include
-#include
#include
#include
#include
@@ -52,42 +51,7 @@
#include
#include
-
-#if (defined BOOST_NO_CXX11_RVALUE_REFERENCES) || (defined BOOST_OPTIONAL_CONFIG_NO_RVALUE_REFERENCES)
-#define BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
-#endif
-
-#if BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION,<=700)
-// AFAICT only Intel 7 correctly resolves the overload set
-// that includes the in-place factory taking functions,
-// so for the other icc versions, in-place factory support
-// is disabled
-#define BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
-#endif
-
-#if BOOST_WORKAROUND(__BORLANDC__, <= 0x551)
-// BCB (5.5.1) cannot parse the nested template struct in an inplace factory.
-#define BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT
-#endif
-
-#if !defined(BOOST_OPTIONAL_NO_INPLACE_FACTORY_SUPPORT) \
- && BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x581) )
-// BCB (up to 5.64) has the following bug:
-// If there is a member function/operator template of the form
-// template mfunc( Expr expr ) ;
-// some calls are resolved to this even if there are other better matches.
-// The effect of this bug is that calls to converting ctors and assignments
-// are incrorrectly sink to this general catch-all member function template as shown above.
-#define BOOST_OPTIONAL_WEAK_OVERLOAD_RESOLUTION
-#endif
-
-#if defined(__GNUC__) && !defined(__INTEL_COMPILER)
-// GCC since 3.3 has may_alias attribute that helps to alleviate optimizer issues with
-// regard to violation of the strict aliasing rules. The optional< T > storage type is marked
-// with this attribute in order to let the compiler know that it will alias objects of type T
-// and silence compilation warnings.
-#define BOOST_OPTIONAL_DETAIL_USE_ATTRIBUTE_MAY_ALIAS
-#endif
+#include
// Daniel Wallin discovered that bind/apply.hpp badly interacts with the apply<>
// member template of a factory as used in the optional<> implementation.
@@ -102,7 +66,6 @@ namespace boost_optional_detail
}
}
-
namespace boost {
class in_place_factory_base ;
@@ -252,7 +215,7 @@ class optional_base : public optional_tag
:
m_initialized(false)
{
- construct(val);
+ construct(val);
}
#ifndef BOOST_OPTIONAL_DETAIL_NO_RVALUE_REFERENCES
@@ -1180,6 +1143,14 @@ class optional
} ;
#endif
+} // namespace boost
+
+#ifndef BOOST_OPTIONAL_CONFIG_DONT_SPECIALIZE_OPTIONAL_REFS
+# include
+#endif
+
+namespace boost {
+
// Returns optional(v)
template
inline
@@ -1277,291 +1248,9 @@ operator<<(std::basic_ostream& os, optional_detail::optiona
return os;
}
-// optional's relational operators ( ==, !=, <, >, <=, >= ) have deep-semantics (compare values).
-// WARNING: This is UNLIKE pointers. Use equal_pointees()/less_pointess() in generic code instead.
-
-
-//
-// optional vs optional cases
-//
-
-template
-inline
-bool operator == ( optional const& x, optional const& y )
-{ return equal_pointees(x,y); }
-
-template
-inline
-bool operator < ( optional const& x, optional const& y )
-{ return less_pointees(x,y); }
-
-template
-inline
-bool operator != ( optional const& x, optional const& y )
-{ return !( x == y ) ; }
-
-template
-inline
-bool operator > ( optional const& x, optional const& y )
-{ return y < x ; }
-
-template
-inline
-bool operator <= ( optional const& x, optional const& y )
-{ return !( y < x ) ; }
-
-template
-inline
-bool operator >= ( optional const& x, optional const& y )
-{ return !( x < y ) ; }
-
-
-//
-// optional vs T cases
-//
-template
-inline
-bool operator == ( optional const& x, T const& y )
-{ return equal_pointees(x, optional(y)); }
-
-template
-inline
-bool operator < ( optional const& x, T const& y )
-{ return less_pointees(x, optional(y)); }
-
-template
-inline
-bool operator != ( optional const& x, T const& y )
-{ return !( x == y ) ; }
-
-template
-inline
-bool operator > ( optional const& x, T const& y )
-{ return y < x ; }
-
-template
-inline
-bool operator <= ( optional const& x, T const& y )
-{ return !( y < x ) ; }
-
-template
-inline
-bool operator >= ( optional const& x, T const& y )
-{ return !( x < y ) ; }
-
-//
-// T vs optional cases
-//
-
-template
-inline
-bool operator == ( T const& x, optional const& y )
-{ return equal_pointees( optional(x), y ); }
-
-template
-inline
-bool operator < ( T const& x, optional const& y )
-{ return less_pointees( optional(x), y ); }
-
-template
-inline
-bool operator != ( T const& x, optional const& y )
-{ return !( x == y ) ; }
-
-template
-inline
-bool operator > ( T const& x, optional const& y )
-{ return y < x ; }
-
-template
-inline
-bool operator <= ( T const& x, optional const& y )
-{ return !( y < x ) ; }
-
-template
-inline
-bool operator >= ( T const& x, optional