Fix bad usage of std::move

Issue #16 describes the problem and solution perfectly.

Updated tests to cover this.

Fixes #16
This commit is contained in:
Ben Clayton 2020-01-24 15:03:29 +00:00 committed by Ben Clayton
parent 3e6cfd6c2f
commit 9a9d46f6b6
2 changed files with 37 additions and 30 deletions

View File

@ -17,7 +17,7 @@
#include <assert.h> #include <assert.h>
#include <type_traits> #include <type_traits>
#include <utility> // std::move #include <utility> // std::move, std::forward
namespace dap { namespace dap {
@ -104,7 +104,7 @@ optional<T>::optional(optional<U>&& other) : set(other.has_value()) {
template <typename T> template <typename T>
template <typename U /*= T*/, typename> template <typename U /*= T*/, typename>
optional<T>::optional(U&& value) : val(std::move(value)), set(true) {} optional<T>::optional(U&& value) : val(std::forward<U>(value)), set(true) {}
template <typename T> template <typename T>
T& optional<T>::value() { T& optional<T>::value() {
@ -153,7 +153,7 @@ optional<T>& optional<T>::operator=(optional&& other) noexcept {
template <typename T> template <typename T>
template <typename U /* = T */, typename> template <typename U /* = T */, typename>
optional<T>& optional<T>::operator=(U&& value) { optional<T>& optional<T>::operator=(U&& value) {
val = std::move(value); val = std::forward<U>(value);
set = true; set = true;
return *this; return *this;
} }

View File

@ -17,23 +17,27 @@
#include "gmock/gmock.h" #include "gmock/gmock.h"
#include "gtest/gtest.h" #include "gtest/gtest.h"
#include <string>
TEST(Optional, EmptyConstruct) { TEST(Optional, EmptyConstruct) {
dap::optional<int> opt; dap::optional<std::string> opt;
ASSERT_FALSE(opt); ASSERT_FALSE(opt);
ASSERT_FALSE(opt.has_value()); ASSERT_FALSE(opt.has_value());
} }
TEST(Optional, ValueConstruct) { TEST(Optional, ValueConstruct) {
dap::optional<int> opt(0); dap::optional<int> opt(10);
ASSERT_TRUE(opt); ASSERT_TRUE(opt);
ASSERT_TRUE(opt.has_value()); ASSERT_TRUE(opt.has_value());
ASSERT_EQ(opt.value(), 10);
} }
TEST(Optional, CopyConstruct) { TEST(Optional, CopyConstruct) {
dap::optional<int> a(10); dap::optional<std::string> a("meow");
dap::optional<int> b(a); dap::optional<std::string> b(a);
ASSERT_EQ(a, b); ASSERT_EQ(a, b);
ASSERT_EQ(b.value(), 10); ASSERT_EQ(a.value(), "meow");
ASSERT_EQ(b.value(), "meow");
} }
TEST(Optional, CopyCastConstruct) { TEST(Optional, CopyCastConstruct) {
@ -44,9 +48,9 @@ TEST(Optional, CopyCastConstruct) {
} }
TEST(Optional, MoveConstruct) { TEST(Optional, MoveConstruct) {
dap::optional<int> a(10); dap::optional<std::string> a("meow");
dap::optional<int> b(std::move(a)); dap::optional<std::string> b(std::move(a));
ASSERT_EQ(b.value(), 10); ASSERT_EQ(b.value(), "meow");
} }
TEST(Optional, MoveCastConstruct) { TEST(Optional, MoveCastConstruct) {
@ -56,33 +60,36 @@ TEST(Optional, MoveCastConstruct) {
} }
TEST(Optional, AssignValue) { TEST(Optional, AssignValue) {
dap::optional<int> a; dap::optional<std::string> a;
a = 10; std::string b = "meow";
ASSERT_EQ(a.value(), 10); a = b;
ASSERT_EQ(a.value(), "meow");
ASSERT_EQ(b, "meow");
} }
TEST(Optional, AssignOptional) { TEST(Optional, AssignOptional) {
dap::optional<int> a; dap::optional<std::string> a;
dap::optional<int> b(10); dap::optional<std::string> b("meow");
a = b; a = b;
ASSERT_EQ(a.value(), 10); ASSERT_EQ(a.value(), "meow");
ASSERT_EQ(b.value(), "meow");
} }
TEST(Optional, MoveAssignOptional) { TEST(Optional, MoveAssignOptional) {
dap::optional<int> a; dap::optional<std::string> a;
dap::optional<int> b(10); dap::optional<std::string> b("meow");
a = std::move(b); a = std::move(b);
ASSERT_EQ(a.value(), 10); ASSERT_EQ(a.value(), "meow");
} }
TEST(Optional, StarDeref) { TEST(Optional, StarDeref) {
dap::optional<int> a(10); dap::optional<std::string> a("meow");
ASSERT_EQ(*a, 10); ASSERT_EQ(*a, "meow");
} }
TEST(Optional, StarDerefConst) { TEST(Optional, StarDerefConst) {
const dap::optional<int> a(10); const dap::optional<std::string> a("meow");
ASSERT_EQ(*a, 10); ASSERT_EQ(*a, "meow");
} }
TEST(Optional, ArrowDeref) { TEST(Optional, ArrowDeref) {
@ -102,15 +109,15 @@ TEST(Optional, ArrowDerefConst) {
} }
TEST(Optional, Value) { TEST(Optional, Value) {
const dap::optional<int> a(10); const dap::optional<std::string> a("meow");
ASSERT_EQ(a.value(), 10); ASSERT_EQ(a.value(), "meow");
} }
TEST(Optional, ValueDefault) { TEST(Optional, ValueDefault) {
const dap::optional<int> a; const dap::optional<std::string> a;
const dap::optional<int> b(20); const dap::optional<std::string> b("woof");
ASSERT_EQ(a.value(10), 10); ASSERT_EQ(a.value("meow"), "meow");
ASSERT_EQ(b.value(10), 20); ASSERT_EQ(b.value("meow"), "woof");
} }
TEST(Optional, CompareLT) { TEST(Optional, CompareLT) {