Utility: nano::optional_ptr (#2605)
* optional_ptr * Implement feedback from Wesley/Guilherme
This commit is contained in:
parent
e10701220f
commit
bac78d0273
3 changed files with 122 additions and 0 deletions
|
|
@ -1,3 +1,4 @@
|
||||||
|
#include <nano/lib/optional_ptr.hpp>
|
||||||
#include <nano/lib/timer.hpp>
|
#include <nano/lib/timer.hpp>
|
||||||
#include <nano/lib/utility.hpp>
|
#include <nano/lib/utility.hpp>
|
||||||
#include <nano/lib/worker.hpp>
|
#include <nano/lib/worker.hpp>
|
||||||
|
|
@ -7,6 +8,33 @@
|
||||||
|
|
||||||
#include <boost/filesystem.hpp>
|
#include <boost/filesystem.hpp>
|
||||||
|
|
||||||
|
TEST (optional_ptr, basic)
|
||||||
|
{
|
||||||
|
struct valtype
|
||||||
|
{
|
||||||
|
int64_t x{ 1 };
|
||||||
|
int64_t y{ 2 };
|
||||||
|
int64_t z{ 3 };
|
||||||
|
};
|
||||||
|
|
||||||
|
nano::optional_ptr<valtype> opt;
|
||||||
|
ASSERT_FALSE (opt);
|
||||||
|
ASSERT_FALSE (opt.is_initialized ());
|
||||||
|
|
||||||
|
{
|
||||||
|
auto val = valtype{};
|
||||||
|
opt = val;
|
||||||
|
ASSERT_LT (sizeof (opt), sizeof (val));
|
||||||
|
std::unique_ptr<valtype> uptr;
|
||||||
|
ASSERT_EQ (sizeof (opt), sizeof (uptr));
|
||||||
|
}
|
||||||
|
ASSERT_TRUE (opt);
|
||||||
|
ASSERT_TRUE (opt.is_initialized ());
|
||||||
|
ASSERT_EQ (opt->x, 1);
|
||||||
|
ASSERT_EQ (opt->y, 2);
|
||||||
|
ASSERT_EQ (opt->z, 3);
|
||||||
|
}
|
||||||
|
|
||||||
TEST (thread, worker)
|
TEST (thread, worker)
|
||||||
{
|
{
|
||||||
std::atomic<bool> passed_sleep{ false };
|
std::atomic<bool> passed_sleep{ false };
|
||||||
|
|
|
||||||
|
|
@ -41,6 +41,7 @@ add_library (nano_lib
|
||||||
memory.cpp
|
memory.cpp
|
||||||
numbers.hpp
|
numbers.hpp
|
||||||
numbers.cpp
|
numbers.cpp
|
||||||
|
optional_ptr.hpp
|
||||||
rep_weights.hpp
|
rep_weights.hpp
|
||||||
rep_weights.cpp
|
rep_weights.cpp
|
||||||
rocksdbconfig.hpp
|
rocksdbconfig.hpp
|
||||||
|
|
|
||||||
93
nano/lib/optional_ptr.hpp
Normal file
93
nano/lib/optional_ptr.hpp
Normal file
|
|
@ -0,0 +1,93 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <nano/lib/utility.hpp>
|
||||||
|
|
||||||
|
#include <cstddef>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
namespace nano
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* A space efficient optional which does heap allocation when needed.
|
||||||
|
* This is an alternative to boost/std::optional when the value type is
|
||||||
|
* large and often not present.
|
||||||
|
*
|
||||||
|
* optional_ptr is similar to using std::unique_ptr as an optional, with the
|
||||||
|
* main difference being that it's copyable.
|
||||||
|
*/
|
||||||
|
template <typename T>
|
||||||
|
class optional_ptr
|
||||||
|
{
|
||||||
|
static_assert (sizeof (T) > alignof (std::max_align_t), "Use [std|boost]::optional");
|
||||||
|
|
||||||
|
public:
|
||||||
|
optional_ptr () = default;
|
||||||
|
|
||||||
|
optional_ptr (T const & value) :
|
||||||
|
ptr (new T{ value })
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
optional_ptr (optional_ptr const & other)
|
||||||
|
{
|
||||||
|
if (other && other.ptr)
|
||||||
|
{
|
||||||
|
ptr = std::make_unique<T> (*other.ptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
optional_ptr & operator= (optional_ptr const & other)
|
||||||
|
{
|
||||||
|
if (other && other.ptr)
|
||||||
|
{
|
||||||
|
ptr = std::make_unique<T> (*other.ptr);
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
T & operator* ()
|
||||||
|
{
|
||||||
|
return *ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
T const & operator* () const
|
||||||
|
{
|
||||||
|
return *ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
T * const operator-> ()
|
||||||
|
{
|
||||||
|
return ptr.operator-> ();
|
||||||
|
}
|
||||||
|
|
||||||
|
T const * const operator-> () const
|
||||||
|
{
|
||||||
|
return ptr.operator-> ();
|
||||||
|
}
|
||||||
|
|
||||||
|
T const * const get () const
|
||||||
|
{
|
||||||
|
debug_assert (is_initialized ());
|
||||||
|
return ptr.get ();
|
||||||
|
}
|
||||||
|
|
||||||
|
T * const get ()
|
||||||
|
{
|
||||||
|
debug_assert (is_initialized ());
|
||||||
|
return ptr.get ();
|
||||||
|
}
|
||||||
|
|
||||||
|
explicit operator bool () const
|
||||||
|
{
|
||||||
|
return static_cast<bool> (ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool is_initialized () const
|
||||||
|
{
|
||||||
|
return static_cast<bool> (ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
std::unique_ptr<T> ptr{ nullptr };
|
||||||
|
};
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue