.. _program_listing_file_include_fastcdr_xcdr_optional.hpp: Program Listing for File optional.hpp ===================================== |exhale_lsh| :ref:`Return to documentation for file ` (``include/fastcdr/xcdr/optional.hpp``) .. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS .. code-block:: cpp // Copyright 2023 Proyectos y Sistemas de Mantenimiento SL (eProsima). // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // #ifndef _FASTCDR_XCDR_OPTIONAL_HPP_ #define _FASTCDR_XCDR_OPTIONAL_HPP_ #include #include #include "detail/optional.hpp" #include "../exceptions/BadOptionalAccessException.hpp" namespace eprosima { namespace fastcdr { struct nullopt_t { constexpr explicit nullopt_t( int) { } }; static constexpr nullopt_t nullopt {0}; template class optional { public: using type = T; optional() = default; optional( const T& val) noexcept { ::new(&storage_.val_)T(val); storage_.engaged_ = true; } optional( T&& val) noexcept { ::new(&storage_.val_)T(std::move(val)); storage_.engaged_ = true; } optional( const optional& val) noexcept { if (val.storage_.engaged_) { ::new(&storage_.val_)T(val.storage_.val_); storage_.engaged_ = true; } } optional( optional&& val) noexcept { if (val.storage_.engaged_) { ::new(&storage_.val_)T(std::move(val.storage_.val_)); storage_.engaged_ = true; } } ~optional() = default; template void emplace( Args&&... _args) { reset(); storage_.val_.T(std::forward(_args)...); storage_.engaged_ = true; } void reset( bool initial_engaged = false) { if (storage_.engaged_) { storage_.val_.~T(); } storage_.engaged_ = initial_engaged; if (storage_.engaged_) { ::new(&storage_.val_)T(); } } T& value()& { if (!storage_.engaged_) { throw exception::BadOptionalAccessException( exception::BadOptionalAccessException::BAD_OPTIONAL_ACCESS_MESSAGE_DEFAULT); } return storage_.val_; } const T& value() const& { if (!storage_.engaged_) { throw exception::BadOptionalAccessException( exception::BadOptionalAccessException::BAD_OPTIONAL_ACCESS_MESSAGE_DEFAULT); } return storage_.val_; } T&& value() && { if (!storage_.engaged_) { throw exception::BadOptionalAccessException( exception::BadOptionalAccessException::BAD_OPTIONAL_ACCESS_MESSAGE_DEFAULT); } return std::move(storage_.val_); } const T&& value() const&& { if (!storage_.engaged_) { throw exception::BadOptionalAccessException( exception::BadOptionalAccessException::BAD_OPTIONAL_ACCESS_MESSAGE_DEFAULT); } return std::move(storage_.val_); } bool has_value() const { return storage_.engaged_; } optional& operator =( const optional& opt) { reset(); storage_.engaged_ = opt.storage_.engaged_; if (opt.storage_.engaged_) { ::new(&storage_.val_)T(opt.storage_.val_); } return *this; } optional& operator =( optional&& opt) { reset(); storage_.engaged_ = opt.storage_.engaged_; if (opt.storage_.engaged_) { ::new(&storage_.val_)T(std::move(opt.storage_.val_)); } return *this; } optional& operator =( const T& val) { reset(); ::new(&storage_.val_)T(val); storage_.engaged_ = true; return *this; } optional& operator =( T&& val) { reset(); ::new(&storage_.val_)T(std::move(val)); storage_.engaged_ = true; return *this; } optional& operator = ( nullopt_t) noexcept { reset(); return *this; } bool operator ==( const optional& opt_val) const { return opt_val.storage_.engaged_ == storage_.engaged_ && (storage_.engaged_ ? opt_val.storage_.val_ == storage_.val_ : true); } bool operator !=( const optional& opt_val) const { return !operator ==(opt_val); } T& operator *() & noexcept { return storage_.val_; } const T& operator *() const& noexcept { return storage_.val_; } T&& operator *() && noexcept { return std::move(storage_.val_); } const T&& operator *() const&& noexcept { return std::move(storage_.val_); } T* operator ->() noexcept { return std::addressof(storage_.val_); } const T* operator ->() const noexcept { return std::addressof(storage_.val_); } explicit operator bool() const noexcept { return storage_.engaged_; } private: detail::optional_storage storage_; }; } // namespace fastcdr } // namespace eprosima #endif //_FASTCDR_XCDR_OPTIONAL_HPP_