BLI: remove blender::Optional in favor of std::optional

`std::optional` can be used now, because we switched to C++17.
This commit is contained in:
Jacques Lucke 2020-06-29 14:29:05 +02:00
parent 4fc5233467
commit 18bff53c99
10 changed files with 17 additions and 266 deletions

View File

@ -25,13 +25,13 @@
*/
#include "BLI_map.hh"
#include "BLI_optional.hh"
#include "BLI_set.hh"
#include "BLI_utility_mixins.hh"
#include "BLI_vector.hh"
#include "BLI_dot_export_attribute_enums.hh"
#include <optional>
#include <sstream>
namespace blender {
@ -197,10 +197,10 @@ class DirectedGraph final : public Graph {
class NodePort {
private:
Node *m_node;
Optional<std::string> m_port_name;
std::optional<std::string> m_port_name;
public:
NodePort(Node &node, Optional<std::string> port_name = {})
NodePort(Node &node, std::optional<std::string> port_name = {})
: m_node(&node), m_port_name(std::move(port_name))
{
}

View File

@ -67,13 +67,13 @@
* interface as blender::Map. This is useful for benchmarking.
*/
#include <optional>
#include <unordered_map>
#include "BLI_array.hh"
#include "BLI_hash.hh"
#include "BLI_hash_tables.hh"
#include "BLI_map_slots.hh"
#include "BLI_optional.hh"
#include "BLI_probing_strategies.hh"
namespace blender {
@ -392,7 +392,7 @@ class Map {
* Get the value that is stored for the given key and remove it from the map. If the key is not
* in the map, a value-less optional is returned.
*/
Optional<Value> pop_try(const Key &key)
std::optional<Value> pop_try(const Key &key)
{
return this->pop_try_as(key);
}
@ -400,7 +400,7 @@ class Map {
/**
* Same as `pop_try`, but accepts other key types that are supported by the hash function.
*/
template<typename ForwardKey> Optional<Value> pop_try_as(const ForwardKey &key)
template<typename ForwardKey> std::optional<Value> pop_try_as(const ForwardKey &key)
{
return this->pop_try__impl(key, m_hash(key));
}
@ -1074,11 +1074,12 @@ class Map {
MAP_SLOT_PROBING_END();
}
template<typename ForwardKey> Optional<Value> pop_try__impl(const ForwardKey &key, uint32_t hash)
template<typename ForwardKey>
std::optional<Value> pop_try__impl(const ForwardKey &key, uint32_t hash)
{
MAP_SLOT_PROBING_BEGIN (hash, slot) {
if (slot.contains(key, m_is_equal, hash)) {
Optional<Value> value = std::move(*slot.value());
std::optional<Value> value = std::move(*slot.value());
slot.remove();
m_removed_slots++;
return value;

View File

@ -1,189 +0,0 @@
/*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/** \file
* \ingroup bli
*
* Simple version of std::optional, which is only available since C++17.
*/
#ifndef __BLI_OPTIONAL_HH__
#define __BLI_OPTIONAL_HH__
#include "BLI_memory_utils.hh"
#include "BLI_utildefines.h"
#include <algorithm>
#include <memory>
namespace blender {
template<typename T> class Optional {
private:
AlignedBuffer<sizeof(T), alignof(T)> m_storage;
bool m_set;
public:
Optional() : m_set(false)
{
}
~Optional()
{
this->reset();
}
Optional(const T &value) : Optional()
{
this->set(value);
}
Optional(T &&value) : Optional()
{
this->set(std::forward<T>(value));
}
Optional(const Optional &other) : Optional()
{
if (other.has_value()) {
this->set(other.value());
}
}
Optional(Optional &&other) : Optional()
{
if (other.has_value()) {
this->set(std::move(other.value()));
}
}
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;
}
const T &value() const
{
BLI_assert(m_set);
return *this->value_ptr();
}
T &value()
{
BLI_assert(m_set);
return *this->value_ptr();
}
void set(const T &value)
{
if (m_set) {
this->value() = value;
}
else {
new ((void *)this->value_ptr()) T(value);
m_set = true;
}
}
void set(T &&value)
{
if (m_set) {
this->value() = std::move(value);
}
else {
new ((void *)this->value_ptr()) T(std::move(value));
m_set = true;
}
}
void set_new(const T &value)
{
BLI_assert(!m_set);
new ((void *)this->value_ptr()) T(value);
m_set = true;
}
void set_new(T &&value)
{
BLI_assert(!m_set);
new ((void *)this->value_ptr()) T(std::move(value));
m_set = true;
}
void reset()
{
if (m_set) {
this->value_ptr()->~T();
m_set = false;
}
}
T extract()
{
BLI_assert(m_set);
T value = std::move(this->value());
this->reset();
return value;
}
T *operator->()
{
return this->value_ptr();
}
T &operator*()
{
return *this->value_ptr();
}
private:
T *value_ptr() const
{
return (T *)m_storage.ptr();
}
};
} /* namespace blender */
#endif /* __BLI_OPTIONAL_HH__ */

View File

@ -225,7 +225,6 @@ set(SRC
BLI_memory_utils.hh
BLI_mempool.h
BLI_noise.h
BLI_optional.hh
BLI_path_util.h
BLI_polyfill_2d.h
BLI_polyfill_2d_beautify.h

View File

@ -54,7 +54,6 @@ namespace DEG {
/* Commonly used types. */
using blender::Map;
using blender::Optional;
using blender::Set;
using blender::Span;
using blender::StringRef;
@ -62,6 +61,7 @@ using blender::StringRefNull;
using blender::Vector;
using blender::VectorSet;
using std::deque;
using std::optional;
using std::pair;
using std::string;
using std::unique_ptr;

View File

@ -172,10 +172,10 @@ void ObjectRuntimeBackup::restore_pose_channel_runtime_data(Object *object)
LISTBASE_FOREACH (bPoseChannel *, pchan, &object->pose->chanbase) {
/* This is nullptr in Edit mode. */
if (pchan->orig_pchan != nullptr) {
Optional<bPoseChannel_Runtime> runtime = pose_channel_runtime_data.pop_try(
optional<bPoseChannel_Runtime> runtime = pose_channel_runtime_data.pop_try(
pchan->orig_pchan);
if (runtime.has_value()) {
pchan->runtime = runtime.extract();
pchan->runtime = *runtime;
}
}
}

View File

@ -24,6 +24,8 @@
* and index.
*/
#include <optional>
#include "FN_spans.hh"
#include "BLI_linear_allocator.hh"
@ -204,7 +206,7 @@ class MutableAttributesRef {
return this->get<T>(m_info->index_of(name));
}
Optional<GMutableSpan> try_get(StringRef name, const CPPType &type) const
std::optional<GMutableSpan> try_get(StringRef name, const CPPType &type) const
{
int index = m_info->try_index_of(name, type);
if (index == -1) {
@ -215,7 +217,7 @@ class MutableAttributesRef {
}
}
template<typename T> Optional<MutableSpan<T>> try_get(StringRef name) const
template<typename T> std::optional<MutableSpan<T>> try_get(StringRef name) const
{
int index = m_info->try_index_of(name);
if (index == -1) {

View File

@ -88,7 +88,7 @@ TEST(map, PopTry)
map.add(1, 5);
map.add(2, 7);
EXPECT_EQ(map.size(), 2u);
Optional<int> value = map.pop_try(4);
std::optional<int> value = map.pop_try(4);
EXPECT_EQ(map.size(), 2u);
EXPECT_FALSE(value.has_value());
value = map.pop_try(2);

View File

@ -1,61 +0,0 @@
#include "BLI_optional.hh"
#include "BLI_strict_flags.h"
#include "testing/testing.h"
#include <string>
using namespace blender;
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());
}
TEST(optional, Extract)
{
Optional<int> a(32);
EXPECT_TRUE(a.has_value());
EXPECT_EQ(a.extract(), 32);
EXPECT_FALSE(a.has_value());
}
TEST(optional, ArrowOperator)
{
Optional<std::string> value = std::string("Hello");
EXPECT_TRUE(value.has_value());
EXPECT_EQ(value->size(), 5);
}
TEST(optional, StarOperator)
{
Optional<std::string> value = std::string("Hello");
EXPECT_TRUE(value.has_value());
std::string &s = *value;
EXPECT_EQ(s.size(), 5);
}

View File

@ -63,7 +63,6 @@ BLENDER_TEST(BLI_math_geom "bf_blenlib")
BLENDER_TEST(BLI_math_matrix "bf_blenlib")
BLENDER_TEST(BLI_math_vector "bf_blenlib")
BLENDER_TEST(BLI_memiter "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_set "bf_blenlib")