Skip to content

Commit

Permalink
Refs #18687. optional documented
Browse files Browse the repository at this point in the history
Signed-off-by: Ricardo González Moreno <[email protected]>
  • Loading branch information
richiware committed Jul 7, 2023
1 parent 01aaa19 commit dda4609
Showing 1 changed file with 107 additions and 4 deletions.
111 changes: 107 additions & 4 deletions include/fastcdr/xcdr/optional.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ struct optional_storage<T, typename std::enable_if<std::is_trivially_destructibl
/* *INDENT-ON* */
} // namespace detail

//! An empty class type used to indicate optional type with uninitialized state.
struct nullopt_t
{
constexpr explicit nullopt_t(
Expand All @@ -77,47 +78,64 @@ struct nullopt_t

};

/*!
* @brief nullopt is a constant of type nullopt_t that is used to indicate optional type with uninitialized state.
*/
static constexpr nullopt_t nullopt {0};

/*!
* @brief This class template manages an optional contained value, i.e. a value that may or may not be present.
*/
template<class T>
class optional
{
public:

using type = T;

//! Default constructor
optional() = default;

//! Copy constructor from an instance of the templated class.
optional(
const T& val) noexcept
{
::new(&storage_.val_)T(val);
storage_.engaged_ = true;
}

//! Move constructor from an instance of the templated class.
optional(
T&& val) noexcept
{
::new(&storage_.val_)T(std::move(val));
storage_.engaged_ = true;
}

//! Copy constructor.
optional(
const optional<T>& val) noexcept
{
::new(&storage_.val_)T(val.storage_.val_);
storage_.engaged_ = val.storage_.engaged_;
}

//! Move constructor.
optional(
optional<T>&& val) noexcept
{
::new(&storage_.val_)T(std::move(val.storage_.val_));
storage_.engaged_ = val.storage_.engaged_;
}

//! Destructor
~optional() = default;

/*!
* @brief Constructs the contained value in-place
*
* @param[in] _args The arguments to pass to the constructor.
*/
template<class ... Args> void emplace(
Args&&... _args)
{
Expand All @@ -126,6 +144,12 @@ class optional
storage_.engaged_ = true;
}

/*!
* @brief Reset the state of the optional
*
* @param[in] initial_engaged True value initializes the state with a default instance of the templated class.
* False value leaves the optional in a uninitialized state.
*/
void reset(
bool initial_engaged = false)
{
Expand All @@ -140,35 +164,65 @@ class optional
}
}

/*!
* @brief Returns the contained value.
*
* @return The contained value.
* @exception exception::BadOptionalAccessException This exception is thrown when the optional is uninitialized.
*/
T& value()&
{
return storage_.engaged_ ? storage_.val_ : throw exception::BadOptionalAccessException(
"Bad optional accesss: value not set");
}

/*!
* @brief Returns the contained value.
*
* @return The contained value.
* @exception exception::BadOptionalAccessException This exception is thrown when the optional is uninitialized.
*/
const T& value() const&
{
return storage_.engaged_ ? storage_.val_ : throw exception::BadOptionalAccessException(
"Bad optional accesss: value not set");
}

/*!
* @brief Returns the contained value.
*
* @return The contained value.
* @exception exception::BadOptionalAccessException This exception is thrown when the optional is uninitialized.
*/
T&& value() &&
{
return storage_.engaged_ ? std::move(storage_.val_) : throw exception::BadOptionalAccessException(
"Bad optional accesss: value not set");
}

/*!
* @brief Returns the contained value.
*
* @return The contained value.
* @exception exception::BadOptionalAccessException This exception is thrown when the optional is uninitialized.
*/
const T&& value() const&&
{
return storage_.engaged_ ? std::move(storage_.val_) : throw exception::BadOptionalAccessException(
"Bad optional accesss: value not set");
}

/*!
* @brief Checks whether the optional contains a value.
*
* @return Whether the optional contains a value.
*/
bool has_value() const
{
return storage_.engaged_;
}

//! Assigns content from an optional.
optional& operator =(
const optional& opt)
{
Expand All @@ -181,6 +235,7 @@ class optional
return *this;
}

//! Assigns content from an optional.
optional& operator =(
optional&& opt)
{
Expand All @@ -193,6 +248,7 @@ class optional
return *this;
}

//! Assigns content from an instance of the templated class.
optional& operator =(
const T& val)
{
Expand All @@ -202,6 +258,7 @@ class optional
return *this;
}

//! Assigns content from an instance of the templated class.
optional& operator =(
T&& val)
{
Expand All @@ -211,56 +268,102 @@ class optional
return *this;
}

//! Unintialize the optional.
optional& operator = (
nullopt_t) noexcept
{
reset();
return *this;
}

//! Compares optional values.
bool operator ==(
const optional& opt_val) const
{
return opt_val.storage_.engaged_ == storage_.engaged_ &&
(storage_.engaged_ ? opt_val.storage_.val_ == storage_.val_ : true);
}

//! Compares optional values.
bool operator !=(
const optional& opt_val) const
{
return !operator ==(opt_val);
}

/*!
* @brief Accesses the contained value.
*
* The behavior is undefined if *this does not contain a value.
*
* @return The contained value.
*/
T& operator *() & noexcept
{
return storage_.val_;
}

/*!
* @brief Accesses the contained value.
*
* The behavior is undefined if *this does not contain a value.
*
* @return The contained value.
*/
const T& operator *() const& noexcept
{
return storage_.val_;
}

/*!
* @brief Accesses the contained value.
*
* The behavior is undefined if *this does not contain a value.
*
* @return The contained value.
*/
T&& operator *() && noexcept
{
return std::move(storage_.val_);
}

/*!
* @brief Accesses the contained value.
*
* The behavior is undefined if *this does not contain a value.
*
* @return The contained value.
*/
const T&& operator *() const&& noexcept
{
return std::move(storage_.val_);
}

/*!
* @brief Accesses the contained value.
*
* The behavior is undefined if *this does not contain a value.
*
* @return The contained value.
*/
T* operator ->() noexcept
{
return std::addressof(storage_.val_);
}

/*!
* @brief Accesses the contained value.
*
* The behavior is undefined if *this does not contain a value.
*
* @return The contained value.
*/
const T* operator ->() const noexcept
{
return std::addressof(storage_.val_);
}

//! Checks whether the optional contains a value.
explicit operator bool() const noexcept
{
return storage_.engaged_;
Expand All @@ -269,9 +372,9 @@ class optional
private:

detail::optional_storage<T> storage_;
};// namespace fastcdr
}; // namespace fastcdr

} // namespace fastcdr
} // namespace eprosima
} // namespace fastcdr
} // namespace eprosima

#endif //_FASTCDR_XCDR_OPTIONAL_HPP_
#endif //_FASTCDR_XCDR_OPTIONAL_HPP_

0 comments on commit dda4609

Please sign in to comment.