From a2268d78b4ecff754e9d2d97de4f4362dd410d06 Mon Sep 17 00:00:00 2001 From: Andrzej Krzemienski Date: Wed, 10 Dec 2014 23:10:07 +0100 Subject: [PATCH] more optional ref tesst this breaks on msvc, but that only reveals the problems that were there anyway. --- test/optional_test_ref_portable_minimum.cpp | 195 ++++++++++++++++++++ 1 file changed, 195 insertions(+) diff --git a/test/optional_test_ref_portable_minimum.cpp b/test/optional_test_ref_portable_minimum.cpp index 6f4ed9a..a4da751 100644 --- a/test/optional_test_ref_portable_minimum.cpp +++ b/test/optional_test_ref_portable_minimum.cpp @@ -67,6 +67,12 @@ struct concrete_type_of typedef Impl type; }; +template <> +struct concrete_type_of +{ + typedef const Impl type; +}; + template struct has_arrow { @@ -83,6 +89,10 @@ int& val(int& i) { return i; } int& val(Abstract& a) { return a.val(); } int& val(ScopeGuard& g) { return g.val(); } +const int& val(const int& i) { return i; } +const int& val(const Abstract& a) { return a.val(); } +const int& val(const ScopeGuard& g) { return g.val(); } + bool operator==(const Abstract& l, const Abstract& r) { return l.val() == r.val(); } bool operator==(const ScopeGuard& l, const ScopeGuard& r) { return l.val() == r.val(); } @@ -90,6 +100,46 @@ bool operator<(const Abstract& l, const Abstract& r) { return l.val() < r.val(); bool operator<(const ScopeGuard& l, const ScopeGuard& r) { return l.val() < r.val(); } // end testable classes +template +typename boost::enable_if< has_arrow >::type +test_arrow_const() +{ + const typename concrete_type_of::type v(2); + optional o(v); + BOOST_TEST(o); + BOOST_TEST_EQ(o->val(), 2); + BOOST_TEST(boost::addressof(o->val()) == boost::addressof(v.val())); +} + +template +typename boost::disable_if< has_arrow >::type +test_arrow_const() +{ +} + +template +typename boost::enable_if< has_arrow >::type +test_arrow_noconst_const() +{ + typename concrete_type_of::type v(2); + optional o(v); + BOOST_TEST(o); + BOOST_TEST_EQ(o->val(), 2); + BOOST_TEST(boost::addressof(o->val()) == boost::addressof(v.val())); + + v.val() = 1; + BOOST_TEST(o); + BOOST_TEST_EQ(o->val(), 1); + BOOST_TEST_EQ(v.val(), 1); + BOOST_TEST(boost::addressof(o->val()) == boost::addressof(v.val())); +} + +template +typename boost::disable_if< has_arrow >::type +test_arrow_noconst_const() +{ +} + template typename boost::enable_if< has_arrow >::type test_arrow() @@ -98,11 +148,20 @@ test_arrow() optional o(v); BOOST_TEST(o); BOOST_TEST_EQ(o->val(), 2); + BOOST_TEST(boost::addressof(o->val()) == boost::addressof(v.val())); + + v.val() = 1; + BOOST_TEST(o); + BOOST_TEST_EQ(o->val(), 1); + BOOST_TEST_EQ(v.val(), 1); + BOOST_TEST(boost::addressof(o->val()) == boost::addressof(v.val())); o->val() = 3; BOOST_TEST(o); BOOST_TEST_EQ(o->val(), 3); BOOST_TEST_EQ(v.val(), 3); + BOOST_TEST(boost::addressof(o->val()) == boost::addressof(v.val())); + } template @@ -127,6 +186,38 @@ void test_not_containing_value_for() BOOST_TEST(o3 == none); } +template +void test_direct_init_for_const() +{ + const typename concrete_type_of::type v(2); + optional o(v); + + BOOST_TEST(o); + BOOST_TEST(o != none); + BOOST_TEST(boost::addressof(*o) == boost::addressof(v)); + BOOST_TEST_EQ(val(*o), val(v)); + BOOST_TEST_EQ(val(*o), 2); +} + +template +void test_direct_init_for_noconst_const() +{ + typename concrete_type_of::type v(2); + optional o(v); + + BOOST_TEST(o); + BOOST_TEST(o != none); + BOOST_TEST(boost::addressof(*o) == boost::addressof(v)); + BOOST_TEST_EQ(val(*o), val(v)); + BOOST_TEST_EQ(val(*o), 2); + + val(v) = 9; + BOOST_TEST(boost::addressof(*o) == boost::addressof(v)); + BOOST_TEST_EQ(val(*o), val(v)); + BOOST_TEST_EQ(val(*o), 9); + BOOST_TEST_EQ(val(v), 9); +} + template void test_direct_init_for() { @@ -173,6 +264,40 @@ void test_clearing_the_value() BOOST_TEST_EQ(val(v), 2); } +template +void test_copy_assignment_for_const() +{ + const typename concrete_type_of::type v(2); + optional o; + o = optional(v); + + BOOST_TEST(o); + BOOST_TEST(o != none); + BOOST_TEST(boost::addressof(*o) == boost::addressof(v)); + BOOST_TEST(val(*o) == val(v)); + BOOST_TEST(val(*o) == 2); +} + +template +void test_copy_assignment_for_noconst_const() +{ + typename concrete_type_of::type v(2); + optional o; + o = optional(v); + + BOOST_TEST(o); + BOOST_TEST(o != none); + BOOST_TEST(boost::addressof(*o) == boost::addressof(v)); + BOOST_TEST(val(*o) == val(v)); + BOOST_TEST(val(*o) == 2); + + val(v) = 9; + BOOST_TEST(boost::addressof(*o) == boost::addressof(v)); + BOOST_TEST_EQ(val(*o), val(v)); + BOOST_TEST_EQ(val(*o), 9); + BOOST_TEST_EQ(val(v), 9); +} + template void test_copy_assignment_for() { @@ -199,6 +324,54 @@ void test_copy_assignment_for() BOOST_TEST_EQ(val(v), 7); } +template +void test_rebinding_assignment_semantics_const() +{ + const typename concrete_type_of::type v(2), w(7); + optional o(v); + + BOOST_TEST(o); + BOOST_TEST(boost::addressof(*o) == boost::addressof(v)); + BOOST_TEST_EQ(val(*o), val(v)); + BOOST_TEST_EQ(val(*o), 2); + + o = optional(w); + BOOST_TEST_EQ(val(v), 2); + + BOOST_TEST(o); + BOOST_TEST(boost::addressof(*o) != boost::addressof(v)); + BOOST_TEST_NE(val(*o), val(v)); + BOOST_TEST_NE(val(*o), 2); + + BOOST_TEST(boost::addressof(*o) == boost::addressof(w)); + BOOST_TEST_EQ(val(*o), val(w)); + BOOST_TEST_EQ(val(*o), 7); +} + +template +void test_rebinding_assignment_semantics_noconst_const() +{ + typename concrete_type_of::type v(2), w(7); + optional o(v); + + BOOST_TEST(o); + BOOST_TEST(boost::addressof(*o) == boost::addressof(v)); + BOOST_TEST_EQ(val(*o), val(v)); + BOOST_TEST_EQ(val(*o), 2); + + o = optional(w); + BOOST_TEST_EQ(val(v), 2); + + BOOST_TEST(o); + BOOST_TEST(boost::addressof(*o) != boost::addressof(v)); + BOOST_TEST_NE(val(*o), val(v)); + BOOST_TEST_NE(val(*o), 2); + + BOOST_TEST(boost::addressof(*o) == boost::addressof(w)); + BOOST_TEST_EQ(val(*o), val(w)); + BOOST_TEST_EQ(val(*o), 7); +} + template void test_rebinding_assignment_semantics() { @@ -432,11 +605,33 @@ void test_optional_ref() test_swap(); } +template +void test_optional_const_ref() +{ + test_not_containing_value_for(); + test_direct_init_for_const(); + test_direct_init_for_noconst_const(); + test_copy_assignment_for_const(); + test_copy_assignment_for_noconst_const(); + test_rebinding_assignment_semantics_const(); + test_rebinding_assignment_semantics_noconst_const(); + test_clearing_the_value(); + test_arrow_const(); + test_arrow_noconst_const(); + test_equality(); + test_order(); + //test_swap(); +} + int main() { test_optional_ref(); test_optional_ref(); //test_optional_ref(); + test_optional_const_ref(); + test_optional_const_ref(); + //test_optional_const_ref(); + return boost::report_errors(); }