diff options
author | Aron Virginas-Tar <Aron.Virginas-Tar@arm.com> | 2019-02-22 17:08:36 +0000 |
---|---|---|
committer | Aron Virginas-Tar <aron.virginas-tar@arm.com> | 2019-02-27 13:40:06 +0000 |
commit | b56292c0040aa125cdaafcee1a4299c5cd144200 (patch) | |
tree | 3ff8908587d065ee4c621db78d4ea26df6500c3e /include/armnn | |
parent | 91c0eff2ff4ff384e013cb69cac1e07e28b9e2b1 (diff) | |
download | armnn-b56292c0040aa125cdaafcee1a4299c5cd144200.tar.gz |
IVGCVSW-2759 Add MakeOptional to enable in-place optional object construction
* Added new argument-forwarding in-place constructor to Optional
* Added MakeOptional utility template to allow for efficient construction
of optional objects
Change-Id: Iec9067fc5c3e109a26c4cc2fe8468260637b66c5
Signed-off-by: Aron Virginas-Tar <Aron.Virginas-Tar@arm.com>
Diffstat (limited to 'include/armnn')
-rw-r--r-- | include/armnn/Optional.hpp | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/include/armnn/Optional.hpp b/include/armnn/Optional.hpp index cfe0d30610..116466d013 100644 --- a/include/armnn/Optional.hpp +++ b/include/armnn/Optional.hpp @@ -30,6 +30,15 @@ namespace armnn // to have default value for an Optional in a function declaration. struct EmptyOptional {}; +// Disambiguation tag that can be passed to the constructor to indicate that +// the contained object should be constructed in-place +struct ConstructInPlace +{ + explicit ConstructInPlace() = default; +}; + +#define CONSTRUCT_IN_PLACE armnn::ConstructInPlace{} + // OptionalBase is the common functionality between reference and non-reference // optional types. class OptionalBase @@ -79,6 +88,13 @@ public: Construct(value); } + template<class... Args> + OptionalReferenceSwitch(ConstructInPlace, Args&&... args) + : Base{} + { + Construct(CONSTRUCT_IN_PLACE, std::forward<Args>(args)...); + } + OptionalReferenceSwitch(const OptionalReferenceSwitch& other) : Base{} { @@ -152,6 +168,13 @@ private: m_HasValue = true; } + template<class... Args> + void Construct(ConstructInPlace, Args&&... args) + { + new (m_Storage) T(std::forward<Args>(args)...); + m_HasValue = true; + } + alignas(alignof(T)) unsigned char m_Storage[sizeof(T)]; }; @@ -181,6 +204,9 @@ public: { } + template<class... Args> + OptionalReferenceSwitch(ConstructInPlace, Args&&... args) = delete; + OptionalReferenceSwitch& operator=(const T value) { m_Storage = &value; @@ -247,6 +273,18 @@ public: Optional(EmptyOptional empty) : BaseSwitch{empty} {} Optional(const Optional& other) : BaseSwitch{other} {} Optional(const BaseSwitch& other) : BaseSwitch{other} {} + + template<class... Args> + explicit Optional(ConstructInPlace, Args&&... args) : + BaseSwitch(CONSTRUCT_IN_PLACE, std::forward<Args>(args)...) {} }; +// Utility template that constructs an object of type T in-place and wraps +// it inside an Optional<T> object +template<typename T, class... Args> +Optional<T> MakeOptional(Args&&... args) +{ + return Optional<T>(CONSTRUCT_IN_PLACE, std::forward<Args>(args)...); +} + } |