27 #include "xlnt/utils/exceptions.hpp" 28 #include <type_traits> 41 #if ((defined(_MSC_VER) && _MSC_VER <= 1900) || (defined(__GNUC__) && __GNUC__ < 5)) 43 #define XLNT_NOEXCEPT_VALUE_COMPAT(...) (false) 45 #define XLNT_NOEXCEPT_VALUE_COMPAT(...) (__VA_ARGS__) 46 using ctor_copy_T_noexcept =
typename std::conditional<std::is_nothrow_copy_constructible<T>{}, std::true_type, std::false_type>::type;
47 using ctor_move_T_noexcept =
typename std::conditional<std::is_nothrow_move_constructible<T>{}, std::true_type, std::false_type>::type;
48 using copy_ctor_noexcept = ctor_copy_T_noexcept;
49 using move_ctor_noexcept = ctor_move_T_noexcept;
50 using set_copy_noexcept_t =
typename std::conditional<std::is_nothrow_copy_constructible<T>{} && std::is_nothrow_assignable<T, T>{}, std::true_type, std::false_type>::type;
51 using set_move_noexcept_t =
typename std::conditional<std::is_nothrow_move_constructible<T>{} && std::is_nothrow_move_assignable<T>{}, std::true_type, std::false_type>::type;
52 using clear_noexcept_t =
typename std::conditional<std::is_nothrow_destructible<T>{}, std::true_type, std::false_type>::type;
69 optional(
const T &value) noexcept(XLNT_NOEXCEPT_VALUE_COMPAT(ctor_copy_T_noexcept{}))
72 new (&storage_) T(value);
79 optional(T &&value) noexcept(XLNT_NOEXCEPT_VALUE_COMPAT(ctor_move_T_noexcept{}))
82 new (&storage_) T(std::move(value));
89 optional(
const optional &other) noexcept(XLNT_NOEXCEPT_VALUE_COMPAT(copy_ctor_noexcept{}))
90 : has_value_(other.has_value_)
94 new (&storage_) T(other.value_ref());
98 std::memset(storage_, 0,
sizeof(T));
107 : has_value_(other.has_value_)
111 new (&storage_) T(std::move(other.value_ref()));
116 std::memset(storage_, 0,
sizeof(T));
126 if (other.has_value_)
128 set(other.value_ref());
143 if (other.has_value_)
145 set(std::move(other.value_ref()));
175 void set(
const T &value) noexcept(XLNT_NOEXCEPT_VALUE_COMPAT(set_copy_noexcept_t{}))
183 new (&storage_) T(value);
191 void set(T &&value) noexcept(XLNT_NOEXCEPT_VALUE_COMPAT(set_move_noexcept_t{}))
199 value_ref() = std::move(value);
203 new (&storage_) T(std::move(value));
229 void clear() noexcept(XLNT_NOEXCEPT_VALUE_COMPAT(clear_noexcept_t{}))
233 reinterpret_cast<T *
>(&storage_)->~T();
275 if (has_value_ != other.has_value_)
283 return value_ref() == other.value_ref();
298 T &value_ref() noexcept
300 return *
reinterpret_cast<T *
>(&storage_);
303 const T &value_ref()
const noexcept
305 return *
reinterpret_cast<const T *
>(&storage_);
309 alignas(T)
unsigned char storage_[
sizeof(T)];
312 #ifdef XLNT_NOEXCEPT_VALUE_COMPAT 313 #undef XLNT_NOEXCEPT_VALUE_COMPAT optional() noexcept
Default contructor. is_set() will be false initially.
Definition: optional.hpp:59
void clear() noexcept(XLNT_NOEXCEPT_VALUE_COMPAT(clear_noexcept_t{}))
After this is called, is_set() will return false until a new value is provided.
Definition: optional.hpp:229
bool is_set() const noexcept
Returns true if this object currently has a value set. This should be called before accessing the val...
Definition: optional.hpp:167
optional & operator=(T &&rhs) noexcept(XLNT_NOEXCEPT_VALUE_COMPAT(set_move_noexcept_t{}))
Assignment operator overload. Equivalent to setting the value using optional::set.
Definition: optional.hpp:220
optional(optional &&other) noexcept(XLNT_NOEXCEPT_VALUE_COMPAT(move_ctor_noexcept{}))
Move constructs this optional from other. Clears the value from other if set noexcept if T move ctor ...
Definition: optional.hpp:106
bool operator==(const optional< T > &other) const noexcept
Returns true if neither this nor other have a value or both have a value and those values are equal a...
Definition: optional.hpp:273
optional(T &&value) noexcept(XLNT_NOEXCEPT_VALUE_COMPAT(ctor_move_T_noexcept{}))
Constructs this optional with a value. noexcept if T move ctor is noexcept
Definition: optional.hpp:79
Enumerates the possible types a cell can be determined by it's current value.
Definition: cell.hpp:36
Exception when getting a class's attribute before being set/initialized, or when setting a class's at...
Definition: exceptions.hpp:171
Many settings in xlnt are allowed to not have a value set. This class encapsulates a value which may ...
Definition: format.hpp:44
optional & operator=(const T &rhs) noexcept(XLNT_NOEXCEPT_VALUE_COMPAT(set_copy_noexcept_t{}))
Assignment operator overload. Equivalent to setting the value using optional::set.
Definition: optional.hpp:211
~optional() noexcept
Destructor cleans up the T instance if set
Definition: optional.hpp:158
optional & operator=(const optional &other) noexcept(XLNT_NOEXCEPT_VALUE_COMPAT(set_copy_noexcept_t{} &&clear_noexcept_t{}))
Copy assignment of this optional from other noexcept if set and clear are noexcept for T& ...
Definition: optional.hpp:124
optional(const T &value) noexcept(XLNT_NOEXCEPT_VALUE_COMPAT(ctor_copy_T_noexcept{}))
Constructs this optional with a value. noexcept if T copy ctor is noexcept
Definition: optional.hpp:69
optional(const optional &other) noexcept(XLNT_NOEXCEPT_VALUE_COMPAT(copy_ctor_noexcept{}))
Copy constructs this optional from other noexcept if T copy ctor is noexcept
Definition: optional.hpp:89
optional & operator=(optional &&other) noexcept(XLNT_NOEXCEPT_VALUE_COMPAT(set_move_noexcept_t{} &&clear_noexcept_t{}))
Move assignment of this optional from other noexcept if set and clear are noexcept for T&& ...
Definition: optional.hpp:141
bool operator!=(const optional< T > &other) const noexcept
Returns false if neither this nor other have a value or both have a value and those values are equal ...
Definition: optional.hpp:291