diff options
Diffstat (limited to 'include/armnn/Optional.hpp')
-rw-r--r-- | include/armnn/Optional.hpp | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/include/armnn/Optional.hpp b/include/armnn/Optional.hpp new file mode 100644 index 0000000000..6fc207f425 --- /dev/null +++ b/include/armnn/Optional.hpp @@ -0,0 +1,123 @@ +// +// Copyright © 2017 Arm Ltd. All rights reserved. +// SPDX-License-Identifier: MIT +// +#pragma once + +#include "Exceptions.hpp" + +namespace armnn +{ + +// NOTE: the members of the Optional class don't follow the ArmNN +// coding convention because the interface to be close to +// the C++-17 interface so we can easily migrate to std::optional +// later. + +template <typename T> +class Optional final +{ +public: + Optional(T&& value) + : m_HasValue{true} + { + new (m_Storage) T(value); + } + + Optional(const T& value) + : m_HasValue{true} + { + new (m_Storage) T(value); + } + + Optional(const Optional& other) + : m_HasValue{false} + { + *this = other; + } + + Optional() noexcept + : m_HasValue{false} + { + } + + ~Optional() + { + reset(); + } + + operator bool() const noexcept + { + return has_value(); + } + + Optional& operator=(T&& value) + { + reset(); + new (m_Storage) T(value); + m_HasValue = true; + return *this; + } + + Optional& operator=(const T& value) + { + reset(); + new(m_Storage) T(value); + m_HasValue = true; + return *this; + } + + Optional& operator=(const Optional& other) + { + reset(); + if (other.has_value()) + { + new (m_Storage) T(other.value()); + m_HasValue = true; + } + + return *this; + } + + const T& value() const + { + if (!has_value()) + { + throw BadOptionalAccessException("Optional has no value"); + } + + auto valuePtr = reinterpret_cast<const T*>(m_Storage); + return *valuePtr; + } + + T& value() + { + if (!has_value()) + { + throw BadOptionalAccessException("Optional has no value"); + } + + auto valuePtr = reinterpret_cast<T*>(m_Storage); + return *valuePtr; + } + + bool has_value() const noexcept + { + return m_HasValue; + } + + void reset() + { + if (has_value()) + { + value().T::~T(); + m_HasValue = false; + } + } + +private: + alignas(alignof(T)) unsigned char m_Storage[sizeof(T)]; + bool m_HasValue; +}; + +} |