[Bf-blender-cvs] [c4d221b1495] functions: simple BLI::optional<T> type (C++11 compatible)
Jacques Lucke
noreply at git.blender.org
Thu Feb 28 14:43:09 CET 2019
Commit: c4d221b14954b49256c62ff54fca0b5d20539885
Author: Jacques Lucke
Date: Thu Feb 28 14:18:06 2019 +0100
Branches: functions
https://developer.blender.org/rBc4d221b14954b49256c62ff54fca0b5d20539885
simple BLI::optional<T> type (C++11 compatible)
===================================================================
A source/blender/blenlib/BLI_optional.hpp
M source/blender/blenlib/CMakeLists.txt
A tests/gtests/blenlib/BLI_optional_test.cc
M tests/gtests/blenlib/CMakeLists.txt
===================================================================
diff --git a/source/blender/blenlib/BLI_optional.hpp b/source/blender/blenlib/BLI_optional.hpp
new file mode 100644
index 00000000000..74d6b2960bb
--- /dev/null
+++ b/source/blender/blenlib/BLI_optional.hpp
@@ -0,0 +1,139 @@
+#pragma once
+
+#include "BLI_utildefines.h"
+
+#include <algorithm>
+#include <memory>
+
+namespace BLI {
+
+ template<typename T>
+ class Optional {
+ private:
+ char m_raw_data[sizeof(T)];
+ bool m_set;
+
+ public:
+ Optional()
+ : m_set(false) {}
+
+ ~Optional()
+ {
+ this->reset();
+ }
+
+ Optional(T &value)
+ : Optional()
+ {
+ this->set(value);
+ }
+
+ Optional(T &&value)
+ : Optional()
+ {
+ this->set(value);
+ }
+
+ Optional(const Optional &other)
+ {
+ if (other.has_value()) {
+ this->set(other.value());
+ }
+ else {
+ m_set = false;
+ }
+ }
+
+ Optional(Optional &&other)
+ {
+ if (other.has_value()) {
+ this->set(std::move(other.value()));
+ }
+ else {
+ m_set = false;
+ }
+ }
+
+ Optional &operator=(const Optional &other)
+ {
+ if (this == &other) {
+ return *this;
+ }
+ if (other.has_value()) {
+ this->set(other.value());
+ }
+ else {
+ this->reset();
+ }
+ return *this;
+ }
+
+ Optional &operator=(Optional &&other)
+ {
+ if (this == &other) {
+ return *this;
+ }
+ if (other.has_value()) {
+ this->set(std::move(other.value()));
+ }
+ else {
+ this->reset();
+ }
+ return *this;
+ }
+
+ bool has_value() const
+ {
+ return m_set;
+ }
+
+ T &value() const
+ {
+ if (m_set) {
+ return *this->value_ptr();
+ }
+ else {
+ BLI_assert(false);
+ return *(T *)nullptr;
+ }
+ }
+
+ void set(T &value)
+ {
+ if (m_set) {
+ std::copy_n(&value, 1, this->value_ptr());
+ }
+ else {
+ std::uninitialized_copy_n(&value, 1, this->value_ptr());
+ m_set = true;
+ }
+ }
+
+ void set(T &&value)
+ {
+ if (m_set) {
+ std::copy_n(&value, 1, this->value_ptr());
+ }
+ else {
+ std::uninitialized_copy_n(&value, 1, this->value_ptr());
+ }
+ }
+
+ void reset()
+ {
+ if (m_set) {
+ this->value_ptr()->~T();
+ m_set = false;
+ }
+ }
+
+
+ private:
+ T *value_ptr() const
+ {
+ return (T *)m_raw_data;
+ }
+
+ };
+
+} /* namespace BLI */
\ No newline at end of file
diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt
index ebe0a00e368..1c9e59ecad7 100644
--- a/source/blender/blenlib/CMakeLists.txt
+++ b/source/blender/blenlib/CMakeLists.txt
@@ -229,6 +229,7 @@ set(SRC
BLI_lazy_init.hpp
BLI_listbase_wrapper.hpp
BLI_mempool.hpp
+ BLI_optional.hpp
BLI_shared.hpp
BLI_small_vector.hpp
BLI_small_map.hpp
diff --git a/tests/gtests/blenlib/BLI_optional_test.cc b/tests/gtests/blenlib/BLI_optional_test.cc
new file mode 100644
index 00000000000..c10ff797722
--- /dev/null
+++ b/tests/gtests/blenlib/BLI_optional_test.cc
@@ -0,0 +1,37 @@
+#include "testing/testing.h"
+#include "BLI_optional.hpp"
+#include <string>
+
+using namespace BLI;
+
+TEST(optional, DefaultConstructor)
+{
+ Optional<int> a;
+ EXPECT_FALSE(a.has_value());
+}
+
+TEST(optional, ValueConstructor)
+{
+ Optional<int> a(5);
+ EXPECT_TRUE(a.has_value());
+ EXPECT_EQ(a.value(), 5);
+}
+
+TEST(optional, CopyConstructor)
+{
+ Optional<std::string> a("Hello");
+ Optional<std::string> b = a;
+ EXPECT_TRUE(a.has_value());
+ EXPECT_TRUE(b.has_value());
+ b.value()[0] = 'T';
+ EXPECT_EQ(a.value(), "Hello");
+ EXPECT_EQ(b.value(), "Tello");
+}
+
+TEST(optional, Reset)
+{
+ Optional<int> a(4);
+ EXPECT_TRUE(a.has_value());
+ a.reset();
+ EXPECT_FALSE(a.has_value());
+}
\ No newline at end of file
diff --git a/tests/gtests/blenlib/CMakeLists.txt b/tests/gtests/blenlib/CMakeLists.txt
index be8afd5ff26..fd8b20b92b7 100644
--- a/tests/gtests/blenlib/CMakeLists.txt
+++ b/tests/gtests/blenlib/CMakeLists.txt
@@ -55,6 +55,7 @@ BLENDER_TEST(BLI_math_color "bf_blenlib")
BLENDER_TEST(BLI_math_geom "bf_blenlib")
BLENDER_TEST(BLI_memiter "bf_blenlib")
BLENDER_TEST(BLI_mempool "bf_blenlib")
+BLENDER_TEST(BLI_optional "bf_blenlib")
BLENDER_TEST(BLI_path_util "${BLI_path_util_extra_libs}")
BLENDER_TEST(BLI_polyfill_2d "bf_blenlib")
BLENDER_TEST(BLI_shared "bf_blenlib")
More information about the Bf-blender-cvs
mailing list