mirror of https://github.com/pvnis/srsRAN_4G.git
adt - add optional construct that closely emulates std::optional<T>
parent
67530687e9
commit
ced757a11b
@ -0,0 +1,117 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* \section COPYRIGHT
|
||||||
|
*
|
||||||
|
* Copyright 2013-2021 Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
* By using this file, you agree to the terms and conditions set
|
||||||
|
* forth in the LICENSE file which can be found at the top level of
|
||||||
|
* the distribution.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef SRSRAN_OPTIONAL_H
|
||||||
|
#define SRSRAN_OPTIONAL_H
|
||||||
|
|
||||||
|
#include "detail/type_storage.h"
|
||||||
|
#include "srsran/common/srsran_assert.h"
|
||||||
|
|
||||||
|
namespace srsran {
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class optional
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
optional() : has_val_(false) {}
|
||||||
|
optional(const T& t) : has_val_(true) { storage.emplace(t); }
|
||||||
|
optional(T&& t) : has_val_(true) { storage.emplace(std::move(t)); }
|
||||||
|
optional(const optional<T>& other) : has_val_(other.has_value())
|
||||||
|
{
|
||||||
|
if (other.has_value()) {
|
||||||
|
storage.copy_ctor(other.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
optional(optional<T>&& other) noexcept : has_val_(other.has_value())
|
||||||
|
{
|
||||||
|
if (other.has_value()) {
|
||||||
|
storage.move_ctor(other.get());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
optional& operator=(const optional<T>& other)
|
||||||
|
{
|
||||||
|
if (this == &other) {
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
copy_if_present_helper(storage, other.storage, has_value(), other.has_value());
|
||||||
|
has_val_ = other.has_value();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
optional& operator=(optional<T>&& other) noexcept
|
||||||
|
{
|
||||||
|
move_if_present_helper(storage, other.storage, has_value(), other.has_value());
|
||||||
|
has_val_ = other.has_value();
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
~optional()
|
||||||
|
{
|
||||||
|
if (has_value()) {
|
||||||
|
storage.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool has_value() const { return has_val_; }
|
||||||
|
explicit operator bool() const { return has_value(); }
|
||||||
|
|
||||||
|
T* operator->() { return &value(); }
|
||||||
|
const T* operator->() const { return &value(); }
|
||||||
|
T& operator*() { return value(); }
|
||||||
|
const T& operator*() const { return value(); }
|
||||||
|
T& value()
|
||||||
|
{
|
||||||
|
srsran_assert(has_val_, "Invalid optional<T> access");
|
||||||
|
return storage.get();
|
||||||
|
}
|
||||||
|
const T& value() const
|
||||||
|
{
|
||||||
|
srsran_assert(has_val_, "Invalid optional<T> access");
|
||||||
|
return storage.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename... Args>
|
||||||
|
void emplace(Args&&... args)
|
||||||
|
{
|
||||||
|
if (has_value()) {
|
||||||
|
storage.destroy();
|
||||||
|
}
|
||||||
|
storage.emplace(std::forward<Args>(args)...);
|
||||||
|
has_val_ = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void reset()
|
||||||
|
{
|
||||||
|
if (has_value()) {
|
||||||
|
storage.destroy();
|
||||||
|
has_val_ = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool has_val_;
|
||||||
|
detail::type_storage<T> storage;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
bool operator==(const optional<T>& lhs, const optional<T>& rhs)
|
||||||
|
{
|
||||||
|
return lhs.has_value() == rhs.has_value() and (not lhs.has_value() or lhs.value() == rhs.value());
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
bool operator!=(const optional<T>& lhs, const optional<T>& rhs)
|
||||||
|
{
|
||||||
|
return not(lhs == rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace srsran
|
||||||
|
|
||||||
|
#endif // SRSRAN_OPTIONAL_H
|
@ -0,0 +1,35 @@
|
|||||||
|
/**
|
||||||
|
*
|
||||||
|
* \section COPYRIGHT
|
||||||
|
*
|
||||||
|
* Copyright 2013-2021 Software Radio Systems Limited
|
||||||
|
*
|
||||||
|
* By using this file, you agree to the terms and conditions set
|
||||||
|
* forth in the LICENSE file which can be found at the top level of
|
||||||
|
* the distribution.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "srsran/adt/optional.h"
|
||||||
|
#include "srsran/common/test_common.h"
|
||||||
|
|
||||||
|
using namespace srsran;
|
||||||
|
|
||||||
|
void test_optional_int()
|
||||||
|
{
|
||||||
|
optional<int> opt, opt2(5);
|
||||||
|
TESTASSERT(not opt.has_value() and opt2.has_value());
|
||||||
|
TESTASSERT(not static_cast<bool>(opt) and static_cast<bool>(opt2));
|
||||||
|
TESTASSERT(opt2.value() == 5 and *opt2 == 5);
|
||||||
|
|
||||||
|
opt = 4;
|
||||||
|
TESTASSERT(opt.has_value());
|
||||||
|
TESTASSERT(opt != opt2);
|
||||||
|
opt2 = 4;
|
||||||
|
TESTASSERT(opt == opt2);
|
||||||
|
}
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
test_optional_int();
|
||||||
|
}
|
Loading…
Reference in New Issue