From 646488e0e2f87e5e77d2e764ce642db2304e9ec0 Mon Sep 17 00:00:00 2001 From: Andrey Semashev Date: Sun, 12 Dec 2010 11:35:19 +0000 Subject: [PATCH] operator>> behavior changed slightly so that the stream is not accessed when unrecognized character sequence is detected. [SVN r67184] --- include/boost/optional/optional_io.hpp | 36 +++++---- test/optional_test.cpp | 108 ++++++++++++++++--------- 2 files changed, 88 insertions(+), 56 deletions(-) diff --git a/include/boost/optional/optional_io.hpp b/include/boost/optional/optional_io.hpp index c5d3c31..9e0c807 100644 --- a/include/boost/optional/optional_io.hpp +++ b/include/boost/optional/optional_io.hpp @@ -13,18 +13,19 @@ #define BOOST_OPTIONAL_OPTIONAL_IO_FLC_19NOV2002_HPP #if defined __GNUC__ -# if (__GNUC__ == 2 && __GNUC_MINOR__ <= 97) +# if (__GNUC__ == 2 && __GNUC_MINOR__ <= 97) # define BOOST_OPTIONAL_NO_TEMPLATED_STREAMS # endif #endif // __GNUC__ #if defined BOOST_OPTIONAL_NO_TEMPLATED_STREAMS # include -#else +#else # include # include -#endif +#endif +#include #include #include "boost/optional/optional.hpp" #include "boost/utility/value_init.hpp" @@ -62,26 +63,29 @@ std::basic_istream& operator>>(std::basic_istream& in, optional& v) #endif { - if ( in.good() ) + if (in.good()) { int d = in.get(); - if ( d == ' ' ) + if (d == ' ') { - T x ; + T x; in >> x; - v = x ; + v = x; } else { - if ( d != '-') - in.setstate( std::ios::failbit ); - - d = in.get(); - - if ( d != '-') - in.setstate( std::ios::failbit ); - - v = optional() ; + if (d == '-') + { + d = in.get(); + + if (d == '-') + { + v = none; + return in; + } + } + + in.setstate( std::ios::failbit ); } } diff --git a/test/optional_test.cpp b/test/optional_test.cpp index e841194..e2e0dd5 100644 --- a/test/optional_test.cpp +++ b/test/optional_test.cpp @@ -158,27 +158,27 @@ void test_basics( T const* ) ob.reset(); check_is_pending_dtor( ARG(T) ) ; check_uninitialized(ob); - + } template void test_conditional_ctor_and_get_valur_or ( T const* ) { TRACE( std::endl << BOOST_CURRENT_FUNCTION ); - + T a(321); - + T z(123); - + optional const cdef0(false,a); - + optional def0(false,a); optional def1 = boost::make_optional(false,a); // T is not within boost so ADL won't find make_optional unqualified check_uninitialized(def0); check_uninitialized(def1); optional const co0(true,a); - + optional o0(true,a); optional o1 = boost::make_optional(true,a); // T is not within boost so ADL won't find make_optional unqualified @@ -186,65 +186,65 @@ void test_conditional_ctor_and_get_valur_or ( T const* ) check_initialized(o1); check_value(o0,a,z); check_value(o1,a,z); - + T b = def0.get_value_or(z); BOOST_CHECK( b == z ) ; - + b = get_optional_value_or(def0,z); BOOST_CHECK( b == z ) ; - + b = o0.get_value_or(z); BOOST_CHECK( b == a ) ; b = get_optional_value_or(o0,z); BOOST_CHECK( b == a ) ; - - + + T const& crz = z ; T& rz = z ; - + T const& crzz = def0.get_value_or(crz); BOOST_CHECK( crzz == crz ) ; - + T& rzz = def0.get_value_or(rz); BOOST_CHECK( rzz == rz ) ; - + T const& crzzz = get_optional_value_or(cdef0,crz); BOOST_CHECK( crzzz == crz ) ; - + T& rzzz = get_optional_value_or(def0,rz); BOOST_CHECK( rzzz == rz ) ; - + T const& crb = o0.get_value_or(crz); BOOST_CHECK( crb == a ) ; - + T& rb = o0.get_value_or(rz); BOOST_CHECK( rb == b ) ; - + T const& crbb = get_optional_value_or(co0,crz); BOOST_CHECK( crbb == b ) ; - + T const& crbbb = get_optional_value_or(o0,crz); BOOST_CHECK( crbbb == b ) ; - + T& rbb = get_optional_value_or(o0,rz); BOOST_CHECK( rbb == b ) ; - + T& ra = a ; - + optional defref(false,ra); BOOST_CHECK(!defref); - + optional ref(true,ra); BOOST_CHECK(!!ref); - + a = T(432); - + BOOST_CHECK( *ref == a ) ; - + T& r1 = defref.get_value_or(z); BOOST_CHECK( r1 == z ) ; - + T& r2 = ref.get_value_or(z); BOOST_CHECK( r2 == a ) ; } @@ -718,7 +718,7 @@ void test_relops( T const* ) optional opt0(v0); optional opt1(v1); optional opt2(v2); - + // Check identity BOOST_CHECK ( def0 == def0 ) ; BOOST_CHECK ( opt0 == opt0 ) ; @@ -756,7 +756,7 @@ void test_relops( T const* ) BOOST_CHECK ( opt1 > opt0 ) ; BOOST_CHECK ( opt1 <= opt2 ) ; BOOST_CHECK ( opt1 >= opt0 ) ; - + // Compare against a value directly BOOST_CHECK ( opt0 == v0 ) ; BOOST_CHECK ( opt0 != v1 ) ; @@ -799,7 +799,7 @@ void test_none( T const* ) 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_CHECK ( non_def >= none ) ; @@ -819,11 +819,11 @@ void test_arrow( T const* ) optional oa(a) ; optional const coa(a) ; - + BOOST_CHECK ( coa->V() == 1234 ) ; - + oa->V() = 4321 ; - + BOOST_CHECK ( a.V() = 1234 ) ; BOOST_CHECK ( (*oa).V() = 4321 ) ; } @@ -1086,7 +1086,7 @@ namespace optional_swap_test x = boost::in_place('\0'); else if ( !hasY ) y = boost::in_place('\0'); - + optional_swap_test::swap(*x,*y); if( !hasX ) @@ -1118,7 +1118,7 @@ template struct optional_swap_should_use_default_constructor< // // Specialization of boost::swap: // -template <> +template <> void swap(optional & x, optional & y) { optional_swap_test::swap(x, y); @@ -1133,25 +1133,25 @@ namespace std { // Specializations of std::swap: // -template <> +template <> void swap(optional_swap_test::class_whose_default_ctor_should_be_used & x, optional_swap_test::class_whose_default_ctor_should_be_used & y) { optional_swap_test::swap(x, y); } -template <> +template <> void swap(optional_swap_test::class_whose_default_ctor_should_not_be_used & x, optional_swap_test::class_whose_default_ctor_should_not_be_used & y) { optional_swap_test::swap(x, y); } -template <> +template <> void swap(optional_swap_test::class_without_default_ctor & x, optional_swap_test::class_without_default_ctor & y) { optional_swap_test::swap(x, y); } -template <> +template <> void swap(optional_swap_test::class_whose_explicit_ctor_should_be_used & x, optional_swap_test::class_whose_explicit_ctor_should_be_used & y) { optional_swap_test::swap(x, y); @@ -1204,7 +1204,7 @@ bool test_swap_function( T const* ) // // Tests whether the optional::swap member function works properly. -// Assumes that T has one data member, of type char. +// Assumes that T has one data member, of type char. // Returns true iff the test is passed. // template @@ -1263,6 +1263,33 @@ void test_swap_tweaking() BOOST_CHECK( test_swap_member_function( ARG(optional_swap_test::template_whose_default_ctor_should_be_used) ) ); } +// Test for support for classes with overridden operator& +class CustomAddressOfClass +{ + int n; + +public: + CustomAddressOfClass() : n(0) {} + CustomAddressOfClass(CustomAddressOfClass const& that) : n(that.n) {} + explicit CustomAddressOfClass(int m) : n(m) {} + int* operator& () { return &n; } + bool operator== (CustomAddressOfClass const& that) const { return n == that.n; } +}; + +void test_custom_addressof_operator() +{ + boost::optional< CustomAddressOfClass > o1(CustomAddressOfClass(10)); + BOOST_CHECK(!!o1); + BOOST_CHECK(o1.get() == CustomAddressOfClass(10)); + + o1 = CustomAddressOfClass(20); + BOOST_CHECK(!!o1); + BOOST_CHECK(o1.get() == CustomAddressOfClass(20)); + + o1 = boost::none; + BOOST_CHECK(!o1); +} + int test_main( int, char* [] ) { try @@ -1273,6 +1300,7 @@ int test_main( int, char* [] ) test_conversions1(); test_conversions2(); test_swap_tweaking(); + test_custom_addressof_operator(); } catch ( ... ) {