diff options
author | David Beck <david.beck@arm.com> | 2018-10-04 15:43:17 +0100 |
---|---|---|
committer | Matthew Bentham <matthew.bentham@arm.com> | 2018-10-10 16:16:58 +0100 |
commit | 5eec11db435a94ba5046ba74edc5c9c412a64e9d (patch) | |
tree | 6a3d9b9126ae449fc5e83838b2eb1765a67d6aad /include/armnn/Optional.hpp | |
parent | d806792f7fbdae2cfa8dcb1eb59b9400b84741da (diff) | |
download | armnn-5eec11db435a94ba5046ba74edc5c9c412a64e9d.tar.gz |
IVGCVSW-1964 : replace optional biases with home-grown Optional
!android-nn-driver:151788
Change-Id: Ibdc41d09b8df05e7a0360dcb8a060860dfb1bd99
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; +}; + +} |