1 #pragma once 2 3 #include <initializer_list> 4 #include <utility> 5 6 #include <absl/types/optional.h> 7 8 #include "chainerx/macro.h" 9 10 namespace chainerx { 11 12 template <typename Container> 13 class OptionalContainerArg { 14 public: 15 using T = typename Container::value_type; 16 17 // ctor for null value OptionalContainerArg(absl::nullopt_t)18 OptionalContainerArg(absl::nullopt_t /*nullopt*/) : opt_{absl::nullopt} {} // NOLINT 19 20 // ctor for single value OptionalContainerArg(const T & value)21 OptionalContainerArg(const T& value) : opt_{Container{{value}}} {} // NOLINT 22 23 // ctors for vector value OptionalContainerArg(std::initializer_list<T> list)24 OptionalContainerArg(std::initializer_list<T> list) : opt_{Container{list.begin(), list.end()}} {} OptionalContainerArg(const Container & v)25 OptionalContainerArg(const Container& v) : opt_{v} {} // NOLINT OptionalContainerArg(Container && v)26 OptionalContainerArg(Container&& v) : opt_{std::move(v)} {} // NOLINT 27 has_value()28 bool has_value() const { return opt_.has_value(); } 29 value()30 Container& value() { return opt_.value(); } 31 value()32 const Container& value() const { return opt_.value(); } 33 34 Container& operator*() { 35 CHAINERX_ASSERT(has_value()); 36 return *opt_; 37 } 38 39 const Container& operator*() const { 40 CHAINERX_ASSERT(has_value()); 41 return *opt_; 42 } 43 44 Container* operator->() { 45 CHAINERX_ASSERT(has_value()); 46 return &*opt_; 47 } 48 49 const Container* operator->() const { 50 CHAINERX_ASSERT(has_value()); 51 return &*opt_; 52 } 53 54 explicit operator bool() const { return has_value(); } 55 56 private: 57 absl::optional<Container> opt_; 58 }; 59 60 } // namespace chainerx 61