Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F340419
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Size
15 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/include/rosa/support/types.hpp b/include/rosa/support/types.hpp
index 74c22f3..e0a69a4 100644
--- a/include/rosa/support/types.hpp
+++ b/include/rosa/support/types.hpp
@@ -1,555 +1,555 @@
//===-- rosa/support/types.hpp ----------------------------------*- C++ -*-===//
//
// The RoSA Framework
//
// Distributed under the terms and conditions of the Boost Software License 1.0.
// See accompanying file LICENSE.
//
// If you did not receive a copy of the license file, see
// http://www.boost.org/LICENSE_1_0.txt.
//
//===----------------------------------------------------------------------===//
///
/// \file rosa/support/types.hpp
///
/// \author David Juhasz (david.juhasz@tuwien.ac.at)
///
/// \date 2017-2019
///
/// \brief Implementation of some basic convenience types.
///
/// \note This implementation is partially based on the implementation of
/// corresponding parts of CAF.
///
//===----------------------------------------------------------------------===//
#ifndef ROSA_SUPPORT_TYPES_HPP
#define ROSA_SUPPORT_TYPES_HPP
#include "rosa/support/debug.hpp"
#include <string>
namespace rosa {
/* ************************************************************************** *
* Unit *
* ************************************************************************** */
/// A safe type to replace \c void.
///
/// \c rosa::UnitType is analogous to \c void, but can be safely returned,
/// stored, etc. to enable higher-order abstraction without cluttering code with
/// exceptions for \c void (which can't be stored, for example).
struct UnitType {
/// Constructor, needs to do nothing.
constexpr UnitType() noexcept = default;
/// Copy-constructor, needs to do nothing.
- constexpr UnitType(const UnitType &) noexcept = default;
+ //constexpr UnitType(const UnitType &) noexcept = default;
};
/// Aliasing \c rosa::UnitType as \c rosa::unit_t.
using unit_t = UnitType;
/// The value of \c rosa::unit_t.
///
/// \note Since a value of \c rosa::UnitType has no state, all instances of
/// \c rosa::UnitType is equal and considered *the \c rosa::unit_t value*.
static constexpr unit_t unit = unit_t{}; // NOLINT
/// \name LiftVoid
/// \brief Lifts a type to avoid \c void.
///
/// A type \c T can be lifted as \code
/// typename LiftVoid<T>::Type
/// \endcode
/// The resulted type is \c rosa::unit_t if \c T is \c void, and \c T itself
/// otherwise.
///@{
/// Definition for the general case.
///
/// \tparam T type to lift
template <typename T> struct LiftVoid { using Type = T; };
/// Specialization for \c void.
template <> struct LiftVoid<void> { using Type = unit_t; };
///@}
/// \name UnliftVoid
/// \brief Unlifts a type already lifted by \c rosa::LiftVoid.
///
/// A type \c T can be unlifted as \code
/// typename UnliftVoid<T>::Type
/// \endcode
/// The resulted type is \c void if \c T is \c rosa::unit_t -- that is \c void
/// lifted by \c rosa::LiftVoid --, and \c T itself otherwise.
///
///@{
/// Definition for the general case.
///
/// \tparam T type to unlift
template <typename T> struct UnliftVoid { using Type = T; };
/// Specialization for \c rosa::unit_t.
template <> struct UnliftVoid<unit_t> { using Type = void; };
///@}
/* ************************************************************************** *
* None *
* ************************************************************************** */
/// Represents *nothing*.
///
/// An instance of the type represents *nothing*, that can be used, e.g., for
/// clearing an instance of \c rosa::Optional by assigning an instance of
/// \c rosa::NoneType to it.
struct NoneType {
/// Constructor, needs to do nothing.
constexpr NoneType(void) = default;
/// Evaluates the instance to \c bool.
///
/// A "nothing" is always evaluates to \c false.
constexpr explicit operator bool(void) const { return false; }
};
/// Aliasing type \c rosa::NoneType as \c rosa::none_t.
using none_t = NoneType;
/// The value of \c rosa::none_t.
///
/// \note Since a value of \c rosa::NoneType has no state, all instances of
/// \c rosa::NoneType is equal and considered *the \c rosa::none_t value*.
static constexpr none_t none = none_t{}; // NOLINT
/* ************************************************************************** *
* Optional *
* ************************************************************************** */
/// \defgroup Optional Specializations of rosa::Optional
///
/// \brief Represents an optional value.
///
/// \note This implementation is compatible with \c std::optional of C++17.
///@{
/// Definition for the general case, optionally storing a value.
///
/// \tparam T type of the optional value
template <class T> class Optional {
public:
using Type = T;
/// Creates an instance without value.
///
/// \note Use it with its default parameter.
Optional(const none_t & = none) : Valid(false) {}
/// Creates a valid instance with value.
///
/// \tparam U type of the \p X
/// \tparam E always use it with default value!
///
/// \param X value to store in the object
///
/// \note The constructor is available for types that are convertible to \p T.
template <class U, class E = typename std::enable_if<
std::is_convertible<U, T>::value>::type>
Optional(U X) : Valid(false) {
cr(std::move(X));
}
/// Creates an instance as a copy of another one.
///
/// \param Other the instance whose state to copy
Optional(const Optional &Other) : Valid(false) {
if (Other.Valid) {
cr(Other.Value);
}
}
/// Creates an instance by moving the state of another one.
///
/// \param Other the instance whose state to obtain
Optional(Optional &&Other) noexcept(
std::is_nothrow_move_constructible<T>::value)
: Valid(false) {
if (Other.Valid) {
cr(std::move(Other.Value));
}
}
/// Destroys \p this object.
~Optional(void) { destroy(); }
/// Updates \p this object by copying the state of another one.
///
/// \param Other the instance whose state to copy
///
/// \return reference of the updated instance
Optional &operator=(const Optional &Other) {
if (Valid) {
if (Other.Valid) {
Value = Other.Value;
} else {
destroy();
}
} else if (Other.Valid) {
cr(Other.Value);
}
return *this;
}
/// Updates \p this object by moving the state of another one.
///
/// \param Other the instance whose state to obtain
///
/// \return reference of the updated instance
Optional &operator=(Optional &&Other) noexcept(
std::is_nothrow_destructible<T>::value
&&std::is_nothrow_move_assignable<T>::value) {
if (Valid) {
if (Other.Valid) {
Value = std::move(Other.Value);
} else {
destroy();
}
} else if (Other.Valid) {
cr(std::move(Other.Value));
}
return *this;
}
/// Checks whether \p this object contains a value.
///
/// \return if \p this object contains a value
explicit operator bool(void) const { return Valid; }
/// Checks whether \p this object does not contain a value.
///
/// \return if \p this object does not contain a value
bool operator!(void)const { return !Valid; }
/// Returns the value stored in \p this object.
///
/// \return reference of the stored value
///
/// \pre \p this object contains a value
T &operator*(void) {
ASSERT(Valid);
return Value;
}
/// Returns the value stored in \p this object.
///
/// \return reference of the stored value
///
/// \pre \p this object contains a value
const T &operator*(void)const {
ASSERT(Valid);
return Value;
}
/// Returns the value stored in \p this object.
///
/// \return pointer to the stored value
///
/// \pre \p this object contains a value
const T *operator->(void)const {
ASSERT(Valid);
return &Value;
}
/// Returns the value stored in \p this object.
///
/// \return pointer of the stored value
///
/// \pre \p this object contains a value
T *operator->(void) {
ASSERT(Valid);
return &Value;
}
/// Returns the value stored in \p this object.
///
/// \return reference of the stored value
///
/// \pre \p this object contains a value
T &value(void) {
ASSERT(Valid);
return Value;
}
/// Returns the value stored in \p this object.
///
/// \return reference of the stored value
///
/// \pre \p this object contains a value
const T &value(void) const {
ASSERT(Valid);
return Value;
}
/// Returns the stored value or a default.
///
/// If \p this object contains a value, then the stored value is returned. A
/// given default value is returned otherwise.
///
/// \param DefaultValue the value to return if \p this object does not contain
/// a value
///
/// \return reference to either the stored value or \p DefaultValue if \p this
/// object does not contain a value
const T &valueOr(const T &DefaultValue) const {
return Valid ? Value : DefaultValue;
}
private:
/// Deallocates the stored value if any.
void destroy(void) {
if (Valid) {
Value.~T();
Valid = false;
}
}
/// Updates the state of \p this object by moving a value into it.
///
/// \tparam V type of \p X
///
/// \param X value to move
///
/// \pre \p this object does not contain a value
template <class V> void cr(V &&X) {
ASSERT(!Valid);
Valid = true;
new (&Value) T(std::forward<V>(X));
}
/// Denotes if \p this object contains a value.
bool Valid;
/// Holds the stored value if any.
union {
T Value; ///< The stored value.
};
};
/// Specialization storing a reference.
///
/// The specialization allows \p rosa::Optional to hold a reference
/// rather than an actual value with minimal overhead.
///
/// \tparam T the base type whose reference is to be stored
template <typename T> class Optional<T &> {
public:
using Type = T;
/// Creates an instance without reference
///
/// \note Use it with its default parameter.
Optional(const none_t & = none) : Value(nullptr) {}
/// Creates a valid instance with reference.
///
/// \param X reference to store in the object
Optional(T &X) : Value(&X) {}
/// Creates a valid instance with reference.
///
/// \param X pointer to store in the object as reference
Optional(T *X) : Value(X) {}
/// Creates an instance as a copy of another one.
///
/// \param Other the instance whose state to copy
Optional(const Optional &Other) = default;
/// Updates \p this object by copying the state of another one.
///
/// \param Other the instance whose state to copy
///
/// \return reference of the updated instance
Optional &operator=(const Optional &Other) = default;
/// Checks whether \p this object contains a reference.
///
/// \return if \p this object contains a reference
explicit operator bool(void) const { return Value != nullptr; }
/// Checks whether \p this object does not contain a reference.
///
/// \return if \p this object does not contain a reference
bool operator!(void)const { return !Value; }
/// Returns the reference stored in \p this object.
///
/// \return the stored reference
///
/// \pre \p this object contains a reference
T &operator*(void) {
ASSERT(Value);
return *Value;
}
/// Returns the value stored in \p this object.
///
/// \return the stored reference
///
/// \pre \p this object contains a reference
const T &operator*(void)const {
ASSERT(Value);
return *Value;
}
/// Returns the value stored in \p this object.
///
/// \return the stored reference
///
/// \pre \p this object contains a reference
T *operator->(void) {
ASSERT(Value);
return Value;
}
/// Returns the value stored in \p this object.
///
/// \return the stored reference
///
/// \pre \p this object contains a reference
const T *operator->(void)const {
ASSERT(Value);
return Value;
}
/// Returns the value stored in \p this object.
///
/// \return the stored reference
///
/// \pre \p this object contains a reference
T &value(void) {
ASSERT(Value);
return *Value;
}
/// Returns the value stored in \p this object.
///
/// \return the stored reference
///
/// \pre \p this object contains a reference
const T &value(void) const {
ASSERT(Value);
return *Value;
}
/// Returns the stored reference or a default.
///
/// If \p this object contains a reference, then the stored reference is
/// returned. A given default value is returned otherwise.
///
/// \param DefaultValue the value to return if \p this object does not contain
/// a reference
///
/// \return either the stored reference or \p DefaultValue if \p this object
/// does not contain a reference
const T &valueOr(const T &DefaultValue) const {
return Value ? Value : DefaultValue;
}
private:
/// The stored reference as a pointer.
T *Value;
};
/// Specialization storing \c void.
///
/// The specialization allows \c rosa::Optional to implement a flag for \c void.
template <> class Optional<void> {
public:
using Type = unit_t;
/// Creates an instance with a \c false flag.
///
/// \note Use it with its default parameter.
Optional(none_t = none) : Value(false) {}
/// Creates an instance with a \c true flag.
///
/// \note The only argument is ignored because it can be *the \c rosa::unit_t
/// value* only.
Optional(unit_t) : Value(true) {}
/// Creates an instance as a copy of another one.
///
/// \param Other the instance whose state to copy
Optional(const Optional &Other) = default;
/// Updates \p this object by copying the state of another one.
///
/// \param Other the instance whose state to copy
///
/// \return reference of the updated instance
Optional &operator=(const Optional &Other) = default;
/// Checks whether \p this object contains a \p true flag.
///
/// \return if \p this object contains a \p true flag.
explicit operator bool(void) const { return Value; }
/// Checks whether \p this object contains a \p false flag.
///
/// \return if \p this object contains a \p false flag.
bool operator!(void)const { return !Value; }
private:
/// The stored flag.
bool Value;
};
///@}
} // End namespace rosa
namespace std {
/// Returns the textual representation of any value of \c rosa::unit_t.
///
/// \return textual representation of \c rosa::UnitType.
inline std::string to_string(const rosa::unit_t &) { return "unit"; }
/// Dumps a \c rosa::Unit to a given \c std::ostream.
///
/// \param [in,out] OS output stream to dump to
/// \param U \c rosa::Unit to dump
///
/// \return \p OS after dumping \p U to it
inline ostream &operator<<(ostream &OS, const rosa::unit_t &U) {
OS << to_string(U);
return OS;
}
/// Returns the textual representation of any value of \c rosa::none_t.
///
/// \return textual representation of \c rosa::NoneType.
inline std::string to_string(const rosa::none_t &) { return "none"; }
/// Dumps a \c rosa::none_t to a given \c std::ostream.
///
/// \param [in,out] OS output stream to dump to
/// \param N \c rosa::none_t to dump
///
/// \return \p OS after dumping \p N to it
inline ostream &operator<<(ostream &OS, const rosa::none_t &N) {
OS << to_string(N);
return OS;
}
} // End namespace std
#endif // ROSA_SUPPORT_TYPES_HPP
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Sat, Apr 26, 10:46 PM (21 h, 37 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
134459
Default Alt Text
(15 KB)
Attached To
Mode
R20 SoC_Rosa_repo
Attached
Detach File
Event Timeline
Log In to Comment