fix optional: add in-place construction, emplace assignment

This commit is contained in:
bolero-MURAKAMI 2013-05-23 20:55:26 +09:00
parent a77fd5ffef
commit e5efbfe340
2 changed files with 178 additions and 51 deletions

View file

@ -17,28 +17,59 @@ namespace testspr {
SPROUT_STATIC_CONSTEXPR auto opt3 = sprout::optional<int>(); SPROUT_STATIC_CONSTEXPR auto opt3 = sprout::optional<int>();
TESTSPR_BOTH_ASSERT(!opt3); TESTSPR_BOTH_ASSERT(!opt3);
} }
{
SPROUT_STATIC_CONSTEXPR auto opt3 = sprout::optional<int>(1234);
TESTSPR_BOTH_ASSERT(!!opt3);
}
{ {
SPROUT_STATIC_CONSTEXPR auto opt3 = sprout::optional<int>(sprout::nullopt); SPROUT_STATIC_CONSTEXPR auto opt3 = sprout::optional<int>(sprout::nullopt);
TESTSPR_BOTH_ASSERT(!opt3); TESTSPR_BOTH_ASSERT(!opt3);
} }
{ {
SPROUT_STATIC_CONSTEXPR auto opt3 = sprout::optional<int>(sprout::nullopt); SPROUT_STATIC_CONSTEXPR auto opt3 = sprout::optional<int>(opt1);
TESTSPR_BOTH_ASSERT(!!opt3);
TESTSPR_BOTH_ASSERT(opt3.get() == 1234);
}
{
SPROUT_STATIC_CONSTEXPR auto opt3 = sprout::optional<int>(sprout::optional<int>(1234));
TESTSPR_BOTH_ASSERT(!!opt3);
TESTSPR_BOTH_ASSERT(opt3.get() == 1234);
}
{
SPROUT_STATIC_CONSTEXPR auto v = 1234;
SPROUT_STATIC_CONSTEXPR auto opt3 = sprout::optional<int>(v);
TESTSPR_BOTH_ASSERT(!!opt3);
TESTSPR_BOTH_ASSERT(opt3.get() == 1234);
}
{
SPROUT_STATIC_CONSTEXPR auto opt3 = sprout::optional<int>(1234);
TESTSPR_BOTH_ASSERT(!!opt3);
TESTSPR_BOTH_ASSERT(opt3.get() == 1234);
}
{
SPROUT_STATIC_CONSTEXPR auto opt3 = sprout::optional<int>(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<int>(false, v);
TESTSPR_BOTH_ASSERT(!opt3); TESTSPR_BOTH_ASSERT(!opt3);
} }
{ {
SPROUT_STATIC_CONSTEXPR auto opt3 = sprout::optional<int>(false, 1234); SPROUT_STATIC_CONSTEXPR auto opt3 = sprout::optional<int>(false, 1234);
TESTSPR_BOTH_ASSERT(!opt3); TESTSPR_BOTH_ASSERT(!opt3);
SPROUT_STATIC_CONSTEXPR auto opt4 = sprout::optional<int>(true, 1234);
TESTSPR_BOTH_ASSERT(!!opt4);
TESTSPR_BOTH_ASSERT(opt4.get() == 1234);
} }
{ {
SPROUT_STATIC_CONSTEXPR auto opt3 = sprout::optional<int>(opt1); SPROUT_STATIC_CONSTEXPR auto v = 1234;
SPROUT_STATIC_CONSTEXPR auto opt3 = sprout::optional<int>(true, v);
TESTSPR_BOTH_ASSERT(!!opt3);
TESTSPR_BOTH_ASSERT(opt3.get() == 1234);
}
{
SPROUT_STATIC_CONSTEXPR auto opt3 = sprout::optional<int>(true, 1234);
TESTSPR_BOTH_ASSERT(!!opt3);
TESTSPR_BOTH_ASSERT(opt3.get() == 1234);
}
{
SPROUT_STATIC_CONSTEXPR auto v = sprout::optional<unsigned>(1234);
SPROUT_STATIC_CONSTEXPR auto opt3 = sprout::optional<int>(v);
TESTSPR_BOTH_ASSERT(!!opt3); TESTSPR_BOTH_ASSERT(!!opt3);
TESTSPR_BOTH_ASSERT(opt3.get() == 1234); TESTSPR_BOTH_ASSERT(opt3.get() == 1234);
} }
@ -54,18 +85,38 @@ namespace testspr {
opt3 = sprout::nullopt; opt3 = sprout::nullopt;
TESTSPR_ASSERT(!opt3); TESTSPR_ASSERT(!opt3);
} }
{
auto opt3 = sprout::optional<int>();
opt3 = 1234;
TESTSPR_ASSERT(!!opt3);
TESTSPR_ASSERT(opt3.get() == 1234);
}
{ {
auto opt3 = sprout::optional<int>(); auto opt3 = sprout::optional<int>();
opt3 = opt1; opt3 = opt1;
TESTSPR_ASSERT(!!opt3); TESTSPR_ASSERT(!!opt3);
TESTSPR_ASSERT(opt3.get() == 1234); TESTSPR_ASSERT(opt3.get() == 1234);
} }
{
auto opt3 = sprout::optional<int>();
opt3 = sprout::optional<int>(1234);
TESTSPR_ASSERT(!!opt3);
TESTSPR_ASSERT(opt3.get() == 1234);
}
{
auto opt3 = sprout::optional<int>();
auto v = 1234;
opt3 = v;
TESTSPR_ASSERT(!!opt3);
TESTSPR_ASSERT(opt3.get() == 1234);
}
{
auto opt3 = sprout::optional<int>();
opt3 = 1234;
TESTSPR_ASSERT(!!opt3);
TESTSPR_ASSERT(opt3.get() == 1234);
}
{
auto opt3 = sprout::optional<int>();
auto v = sprout::optional<unsigned>(1234);
opt3 = v;
TESTSPR_ASSERT(!!opt3);
TESTSPR_ASSERT(opt3.get() == 1234);
}
{ {
auto opt3 = sprout::optional<int>(); auto opt3 = sprout::optional<int>();
opt3 = sprout::optional<unsigned>(1234); opt3 = sprout::optional<unsigned>(1234);
@ -73,12 +124,39 @@ namespace testspr {
TESTSPR_ASSERT(opt3.get() == 1234); TESTSPR_ASSERT(opt3.get() == 1234);
} }
// emplace
{
auto opt3 = sprout::optional<int>();
opt3.emplace(1234);
TESTSPR_ASSERT(!!opt3);
TESTSPR_ASSERT(opt3.get() == 1234);
}
// assign // assign
{ {
auto opt3 = sprout::optional<int>(1234); auto opt3 = sprout::optional<int>(1234);
opt3.assign(sprout::nullopt); opt3.assign(sprout::nullopt);
TESTSPR_ASSERT(!opt3); TESTSPR_ASSERT(!opt3);
} }
{
auto opt3 = sprout::optional<int>();
opt3.assign(opt1);
TESTSPR_ASSERT(!!opt3);
TESTSPR_ASSERT(opt3.get() == 1234);
}
{
auto opt3 = sprout::optional<int>();
opt3.assign(sprout::optional<int>(1234));
TESTSPR_ASSERT(!!opt3);
TESTSPR_ASSERT(opt3.get() == 1234);
}
{
auto opt3 = sprout::optional<int>();
auto v = 1234;
opt3.assign(v);
TESTSPR_ASSERT(!!opt3);
TESTSPR_ASSERT(opt3.get() == 1234);
}
{ {
auto opt3 = sprout::optional<int>(); auto opt3 = sprout::optional<int>();
opt3.assign(1234); opt3.assign(1234);
@ -87,7 +165,8 @@ namespace testspr {
} }
{ {
auto opt3 = sprout::optional<int>(); auto opt3 = sprout::optional<int>();
opt3.assign(opt1); auto v = sprout::optional<unsigned>(1234);
opt3.assign(v);
TESTSPR_ASSERT(!!opt3); TESTSPR_ASSERT(!!opt3);
TESTSPR_ASSERT(opt3.get() == 1234); TESTSPR_ASSERT(opt3.get() == 1234);
} }
@ -109,6 +188,13 @@ namespace testspr {
opt3.reset(sprout::nullopt); opt3.reset(sprout::nullopt);
TESTSPR_ASSERT(!opt3); TESTSPR_ASSERT(!opt3);
} }
{
auto opt3 = sprout::optional<int>();
auto v = 1234;
opt3.reset(v);
TESTSPR_ASSERT(!!opt3);
TESTSPR_ASSERT(opt3.get() == 1234);
}
{ {
auto opt3 = sprout::optional<int>(); auto opt3 = sprout::optional<int>();
opt3.reset(1234); opt3.reset(1234);
@ -134,40 +220,6 @@ namespace testspr {
TESTSPR_ASSERT(opt4.get() == 1234); TESTSPR_ASSERT(opt4.get() == 1234);
} }
// operator*
TESTSPR_BOTH_ASSERT(*opt1 == 1234);
{
auto opt3 = sprout::optional<int>(1234);
TESTSPR_ASSERT(*opt3 == 1234);
*opt3 = 12345;
TESTSPR_ASSERT(*opt3 == 12345);
}
// get
TESTSPR_BOTH_ASSERT(opt1.get() == 1234);
{
auto opt3 = sprout::optional<int>(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<int>(1234);
int v = 12345;
TESTSPR_ASSERT(opt3.get_value_or(v) == 1234);
}
{
auto opt3 = sprout::optional<int>();
int v = 12345;
TESTSPR_ASSERT(opt3.get_value_or(v) == 12345);
}
// operator-> // operator->
{ {
SPROUT_STATIC_CONSTEXPR auto opt3 = sprout::make_optional(testspr::is_odd<int>()); SPROUT_STATIC_CONSTEXPR auto opt3 = sprout::make_optional(testspr::is_odd<int>());
@ -198,6 +250,64 @@ namespace testspr {
TESTSPR_ASSERT(*opt3.get_ptr() == 12345); TESTSPR_ASSERT(*opt3.get_ptr() == 12345);
} }
// operator*
TESTSPR_BOTH_ASSERT(*opt1 == 1234);
{
auto opt3 = sprout::optional<int>(1234);
TESTSPR_ASSERT(*opt3 == 1234);
*opt3 = 12345;
TESTSPR_ASSERT(*opt3 == 12345);
}
// value
TESTSPR_BOTH_ASSERT(opt1.value() == 1234);
{
auto opt3 = sprout::optional<int>(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<int>(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<int>(1234);
int v = 12345;
TESTSPR_ASSERT(opt3.value_or(v) == 1234);
}
{
auto opt3 = sprout::optional<int>();
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<int>(1234);
int v = 12345;
TESTSPR_ASSERT(opt3.get_value_or(v) == 1234);
}
{
auto opt3 = sprout::optional<int>();
int v = 12345;
TESTSPR_ASSERT(opt3.get_value_or(v) == 12345);
}
// operator bool // operator bool
TESTSPR_BOTH_ASSERT(static_cast<bool>(opt1)); TESTSPR_BOTH_ASSERT(static_cast<bool>(opt1));
TESTSPR_BOTH_ASSERT(!static_cast<bool>(opt2)); TESTSPR_BOTH_ASSERT(!static_cast<bool>(opt2));

View file

@ -151,6 +151,23 @@ namespace sprout {
return *this; return *this;
} }
template<
typename... Args,
typename = typename std::enable_if<std::is_constructible<T, Args&&...>::value>::type
>
void emplace(Args&&... args) {
optional temp(sprout::in_place, sprout::forward<Args>(args)...);
temp.swap(*this);
}
template<
typename U, typename... Args,
typename = typename std::enable_if<std::is_constructible<T, std::initializer_list<U>&, Args&&...>::value>::type
>
void emplace(std::initializer_list<U> il, Args&&... args) {
optional temp(sprout::in_place, il, sprout::forward<Args>(args)...);
temp.swap(*this);
}
void assign(sprout::nullopt_t) SPROUT_NOEXCEPT { void assign(sprout::nullopt_t) SPROUT_NOEXCEPT {
destroy(); destroy();
} }