#ifndef OPTIONAL_HPP
#define OPTIONAL_HPP
-/*
- * After project conversion to C++17 standard this template class will be deleted
+/**
+ * Minimalistic implementation of standard library std::optional (c++17) for c++11 compiler.
+ *
+ * After project conversion to C++17 standard, this template class will be deleted and
+ * Optional will point to std::optional.
*
* Allowed operations (note, to make code simplier, than original, value class must have accessible copy and move constructor):
* - constructing empty (valueless) object
template <typename A>
class Optional
{
+ /// \cond
union {
A place;
};
bool hasValue = false;
+ /// \endcond
public:
+ /**
+ * @brief Empty constructor.
+ * Creates empty Optional object, which will be false in boolean context.
+ * So:
+ * \code{.cpp}
+ * Optional<int> o;
+ * if (o) printf("1\n");
+ * \endcode
+ * won't print 1.
+ */
Optional() {}
+ /**
+ * @brief Single element constructor, when implicit convertion can be applied.
+ *
+ * This constructor will be selected, when type of given argument (U) is
+ * implicitly convertable to expected type A. In other words following
+ * code must be valid:
+ * \code{.cpp}
+ * A foo() {
+ * return U();
+ * }
+ * \endcode
+ *
+ * @param a value held by Optional object will be initialized from a.
+ */
template < typename U = A, typename std::enable_if <
std::is_convertible < U &&, A >::value &&
std::is_constructible < A, U && >::value &&
{
}
+ /**
+ * @brief Single element constructor, when only explicit convertion can be applied.
+ *
+ * This constructor will be selected, when type of given argument (U) is
+ * convertable to expected type A.
+ *
+ * @param a value held by Optional object will be initialized from a.
+ */
template < typename U = A, typename std::enable_if <
!std::is_convertible < U &&, A >::value &&
std::is_constructible < A, U && >::value &&
{
}
+ /**
+ * @brief Copy constructor.
+ *
+ * @param v Optional value to copy from. Will cause to copy data held by object v,
+ * if v has data.
+ */
Optional(const Optional &v) : hasValue(v.hasValue)
{
if (hasValue) new (&place) A(v.place);
}
+ /**
+ * @brief Move constructor.
+ *
+ * @param v Optional value to copy from. Will move data help by v, if any.
+ * After construction \code{.cpp} bool(v) \endcode will be false.
+ */
Optional(Optional &&v) : hasValue(v.hasValue)
{
if (hasValue) new (&place) A(std::move(v.place));
}
+ /**
+ * @brief Destructor.
+ */
~Optional()
{
if (hasValue) {
}
}
+ /**
+ * @brief Explicit bool operator
+ *
+ * Will return true if and only if object is helding data.
+ */
explicit operator bool () const
{
return hasValue;
}
+ /**
+ * @brief Accessor (*) operator
+ *
+ * Will return modifiable reference to held object. Will assert, if not object is held.
+ */
A &operator * ()
{
ASSERT(hasValue, "Object is not initialized");
return place;
}
+ /**
+ * @brief Accessor (*) const operator
+ *
+ * Will return const reference to held object. Will assert, if not object is held.
+ */
const A &operator * () const
{
ASSERT(hasValue, "Object is not initialized");
return place;
}
+ /**
+ * @brief Accessor (->) operator
+ *
+ * Will return pointer to held object allowing access to the value's members.
+ * Will assert, if not object is held.
+ */
A *operator -> ()
{
ASSERT(hasValue, "Object is not initialized");
return &place;
}
+ /**
+ * @brief Accessor (->) operator
+ *
+ * Will return pointer to (const) held object allowing access to the value's members.
+ * Will assert, if not object is held.
+ */
const A *operator -> () const
{
ASSERT(hasValue, "Object is not initialized");
return &place;
}
+ /**
+ * @brief Assignment operator
+ *
+ * Will copy held value from v, if any.
+ *
+ * @param v Value to copy from
+ */
Optional &operator = (const Optional &v)
{
if (this != &v) {
return *this;
}
+ /**
+ * @brief Assignment move operator
+ *
+ * Will move held value from v, if any. In all cases v won't held a value
+ * after assignment is done.
+ *
+ * @param v Value to copy from
+ */
Optional &operator = (Optional &&v)
{
if (this != &v) {
return *this;
}
+ /**
+ * @brief Assignment operator from value of type held.
+ *
+ * Will initialize held value from given parameter a.
+ * Type of the parameter must be the same (barring cv convertions),
+ * as the type of the value held.
+ *
+ * @param a Value to copy from
+ */
template < class U, class = typename std::enable_if
<
std::is_same<typename std::remove_reference<U>::type, A>::value &&