From e5efbfe340517bec875432bf2a4c1cf99778a714 Mon Sep 17 00:00:00 2001 From: bolero-MURAKAMI Date: Thu, 23 May 2013 20:55:26 +0900 Subject: [PATCH] fix optional: add in-place construction, emplace assignment --- libs/optional/test/optional.cpp | 212 ++++++++++++++++++++++++-------- sprout/optional/optional.hpp | 17 +++ 2 files changed, 178 insertions(+), 51 deletions(-) diff --git a/libs/optional/test/optional.cpp b/libs/optional/test/optional.cpp index 6407ac14..37f5b9e9 100644 --- a/libs/optional/test/optional.cpp +++ b/libs/optional/test/optional.cpp @@ -17,28 +17,59 @@ namespace testspr { SPROUT_STATIC_CONSTEXPR auto opt3 = sprout::optional(); TESTSPR_BOTH_ASSERT(!opt3); } - { - SPROUT_STATIC_CONSTEXPR auto opt3 = sprout::optional(1234); - TESTSPR_BOTH_ASSERT(!!opt3); - } { SPROUT_STATIC_CONSTEXPR auto opt3 = sprout::optional(sprout::nullopt); TESTSPR_BOTH_ASSERT(!opt3); } { - SPROUT_STATIC_CONSTEXPR auto opt3 = sprout::optional(sprout::nullopt); + SPROUT_STATIC_CONSTEXPR auto opt3 = sprout::optional(opt1); + TESTSPR_BOTH_ASSERT(!!opt3); + TESTSPR_BOTH_ASSERT(opt3.get() == 1234); + } + { + SPROUT_STATIC_CONSTEXPR auto opt3 = sprout::optional(sprout::optional(1234)); + TESTSPR_BOTH_ASSERT(!!opt3); + TESTSPR_BOTH_ASSERT(opt3.get() == 1234); + } + { + SPROUT_STATIC_CONSTEXPR auto v = 1234; + SPROUT_STATIC_CONSTEXPR auto opt3 = sprout::optional(v); + TESTSPR_BOTH_ASSERT(!!opt3); + TESTSPR_BOTH_ASSERT(opt3.get() == 1234); + } + { + SPROUT_STATIC_CONSTEXPR auto opt3 = sprout::optional(1234); + TESTSPR_BOTH_ASSERT(!!opt3); + TESTSPR_BOTH_ASSERT(opt3.get() == 1234); + } + { + SPROUT_STATIC_CONSTEXPR auto opt3 = sprout::optional(sprout::in_place, 1234); + TESTSPR_BOTH_ASSERT(!!opt3); + TESTSPR_BOTH_ASSERT(opt3.get() == 1234); + } + { + SPROUT_STATIC_CONSTEXPR auto v = 1234; + SPROUT_STATIC_CONSTEXPR auto opt3 = sprout::optional(false, v); TESTSPR_BOTH_ASSERT(!opt3); } { SPROUT_STATIC_CONSTEXPR auto opt3 = sprout::optional(false, 1234); TESTSPR_BOTH_ASSERT(!opt3); - - SPROUT_STATIC_CONSTEXPR auto opt4 = sprout::optional(true, 1234); - TESTSPR_BOTH_ASSERT(!!opt4); - TESTSPR_BOTH_ASSERT(opt4.get() == 1234); } { - SPROUT_STATIC_CONSTEXPR auto opt3 = sprout::optional(opt1); + SPROUT_STATIC_CONSTEXPR auto v = 1234; + SPROUT_STATIC_CONSTEXPR auto opt3 = sprout::optional(true, v); + TESTSPR_BOTH_ASSERT(!!opt3); + TESTSPR_BOTH_ASSERT(opt3.get() == 1234); + } + { + SPROUT_STATIC_CONSTEXPR auto opt3 = sprout::optional(true, 1234); + TESTSPR_BOTH_ASSERT(!!opt3); + TESTSPR_BOTH_ASSERT(opt3.get() == 1234); + } + { + SPROUT_STATIC_CONSTEXPR auto v = sprout::optional(1234); + SPROUT_STATIC_CONSTEXPR auto opt3 = sprout::optional(v); TESTSPR_BOTH_ASSERT(!!opt3); TESTSPR_BOTH_ASSERT(opt3.get() == 1234); } @@ -54,18 +85,38 @@ namespace testspr { opt3 = sprout::nullopt; TESTSPR_ASSERT(!opt3); } - { - auto opt3 = sprout::optional(); - opt3 = 1234; - TESTSPR_ASSERT(!!opt3); - TESTSPR_ASSERT(opt3.get() == 1234); - } { auto opt3 = sprout::optional(); opt3 = opt1; TESTSPR_ASSERT(!!opt3); TESTSPR_ASSERT(opt3.get() == 1234); } + { + auto opt3 = sprout::optional(); + opt3 = sprout::optional(1234); + TESTSPR_ASSERT(!!opt3); + TESTSPR_ASSERT(opt3.get() == 1234); + } + { + auto opt3 = sprout::optional(); + auto v = 1234; + opt3 = v; + TESTSPR_ASSERT(!!opt3); + TESTSPR_ASSERT(opt3.get() == 1234); + } + { + auto opt3 = sprout::optional(); + opt3 = 1234; + TESTSPR_ASSERT(!!opt3); + TESTSPR_ASSERT(opt3.get() == 1234); + } + { + auto opt3 = sprout::optional(); + auto v = sprout::optional(1234); + opt3 = v; + TESTSPR_ASSERT(!!opt3); + TESTSPR_ASSERT(opt3.get() == 1234); + } { auto opt3 = sprout::optional(); opt3 = sprout::optional(1234); @@ -73,12 +124,39 @@ namespace testspr { TESTSPR_ASSERT(opt3.get() == 1234); } + // emplace + { + auto opt3 = sprout::optional(); + opt3.emplace(1234); + TESTSPR_ASSERT(!!opt3); + TESTSPR_ASSERT(opt3.get() == 1234); + } + // assign { auto opt3 = sprout::optional(1234); opt3.assign(sprout::nullopt); TESTSPR_ASSERT(!opt3); } + { + auto opt3 = sprout::optional(); + opt3.assign(opt1); + TESTSPR_ASSERT(!!opt3); + TESTSPR_ASSERT(opt3.get() == 1234); + } + { + auto opt3 = sprout::optional(); + opt3.assign(sprout::optional(1234)); + TESTSPR_ASSERT(!!opt3); + TESTSPR_ASSERT(opt3.get() == 1234); + } + { + auto opt3 = sprout::optional(); + auto v = 1234; + opt3.assign(v); + TESTSPR_ASSERT(!!opt3); + TESTSPR_ASSERT(opt3.get() == 1234); + } { auto opt3 = sprout::optional(); opt3.assign(1234); @@ -87,7 +165,8 @@ namespace testspr { } { auto opt3 = sprout::optional(); - opt3.assign(opt1); + auto v = sprout::optional(1234); + opt3.assign(v); TESTSPR_ASSERT(!!opt3); TESTSPR_ASSERT(opt3.get() == 1234); } @@ -109,6 +188,13 @@ namespace testspr { opt3.reset(sprout::nullopt); TESTSPR_ASSERT(!opt3); } + { + auto opt3 = sprout::optional(); + auto v = 1234; + opt3.reset(v); + TESTSPR_ASSERT(!!opt3); + TESTSPR_ASSERT(opt3.get() == 1234); + } { auto opt3 = sprout::optional(); opt3.reset(1234); @@ -134,40 +220,6 @@ namespace testspr { TESTSPR_ASSERT(opt4.get() == 1234); } - // operator* - TESTSPR_BOTH_ASSERT(*opt1 == 1234); - { - auto opt3 = sprout::optional(1234); - TESTSPR_ASSERT(*opt3 == 1234); - - *opt3 = 12345; - TESTSPR_ASSERT(*opt3 == 12345); - } - - // get - TESTSPR_BOTH_ASSERT(opt1.get() == 1234); - { - auto opt3 = sprout::optional(1234); - TESTSPR_ASSERT(opt3.get() == 1234); - - opt3.get() = 12345; - TESTSPR_ASSERT(opt3.get() == 12345); - } - - // get_value_or - TESTSPR_BOTH_ASSERT(opt1.get_value_or(12345) == 1234); - TESTSPR_BOTH_ASSERT(opt2.get_value_or(12345) == 12345); - { - auto opt3 = sprout::optional(1234); - int v = 12345; - TESTSPR_ASSERT(opt3.get_value_or(v) == 1234); - } - { - auto opt3 = sprout::optional(); - int v = 12345; - TESTSPR_ASSERT(opt3.get_value_or(v) == 12345); - } - // operator-> { SPROUT_STATIC_CONSTEXPR auto opt3 = sprout::make_optional(testspr::is_odd()); @@ -198,6 +250,64 @@ namespace testspr { TESTSPR_ASSERT(*opt3.get_ptr() == 12345); } + // operator* + TESTSPR_BOTH_ASSERT(*opt1 == 1234); + { + auto opt3 = sprout::optional(1234); + TESTSPR_ASSERT(*opt3 == 1234); + + *opt3 = 12345; + TESTSPR_ASSERT(*opt3 == 12345); + } + + // value + TESTSPR_BOTH_ASSERT(opt1.value() == 1234); + { + auto opt3 = sprout::optional(1234); + TESTSPR_ASSERT(opt3.value() == 1234); + + opt3.value() = 12345; + TESTSPR_ASSERT(opt3.value() == 12345); + } + + // get + TESTSPR_BOTH_ASSERT(opt1.get() == 1234); + { + auto opt3 = sprout::optional(1234); + TESTSPR_ASSERT(opt3.get() == 1234); + + opt3.get() = 12345; + TESTSPR_ASSERT(opt3.get() == 12345); + } + + // value_or + TESTSPR_BOTH_ASSERT(opt1.value_or(12345) == 1234); + TESTSPR_BOTH_ASSERT(opt2.value_or(12345) == 12345); + { + auto opt3 = sprout::optional(1234); + int v = 12345; + TESTSPR_ASSERT(opt3.value_or(v) == 1234); + } + { + auto opt3 = sprout::optional(); + int v = 12345; + TESTSPR_ASSERT(opt3.value_or(v) == 12345); + } + + // get_value_or + TESTSPR_BOTH_ASSERT(opt1.get_value_or(12345) == 1234); + TESTSPR_BOTH_ASSERT(opt2.get_value_or(12345) == 12345); + { + auto opt3 = sprout::optional(1234); + int v = 12345; + TESTSPR_ASSERT(opt3.get_value_or(v) == 1234); + } + { + auto opt3 = sprout::optional(); + int v = 12345; + TESTSPR_ASSERT(opt3.get_value_or(v) == 12345); + } + // operator bool TESTSPR_BOTH_ASSERT(static_cast(opt1)); TESTSPR_BOTH_ASSERT(!static_cast(opt2)); diff --git a/sprout/optional/optional.hpp b/sprout/optional/optional.hpp index d8800af0..38a6654b 100644 --- a/sprout/optional/optional.hpp +++ b/sprout/optional/optional.hpp @@ -151,6 +151,23 @@ namespace sprout { return *this; } + template< + typename... Args, + typename = typename std::enable_if::value>::type + > + void emplace(Args&&... args) { + optional temp(sprout::in_place, sprout::forward(args)...); + temp.swap(*this); + } + template< + typename U, typename... Args, + typename = typename std::enable_if&, Args&&...>::value>::type + > + void emplace(std::initializer_list il, Args&&... args) { + optional temp(sprout::in_place, il, sprout::forward(args)...); + temp.swap(*this); + } + void assign(sprout::nullopt_t) SPROUT_NOEXCEPT { destroy(); }