Page MenuHomePhorge

AgentHandle.hpp
No OneTemporary

Size
8 KB
Referenced Files
None
Subscribers
None

AgentHandle.hpp

//===-- rosa/core/AgentHandle.hpp -------------------------------*- C++ -*-===//
//
// The RoSA Framework
//
//===----------------------------------------------------------------------===//
///
/// \file rosa/core/AgentHandle.hpp
///
/// \author David Juhasz (david.juhasz@tuwien.ac.at)
///
/// \date 2017
///
/// \brief Declaration of a handle for \c rosa::Agent.
///
//===----------------------------------------------------------------------===//
#ifndef ROSA_CORE_AGENTHANDLE_HPP
#define ROSA_CORE_AGENTHANDLE_HPP
#include "rosa/core/AbstractAgent.hpp"
namespace rosa {
/// Wraps an actual \c rosa::Agent to decouple its public interface.
/// \note Such decoupling might be necessary when operating with remote
/// *systems*, sometime in the future.
class AgentHandle : public AbstractAgent<AgentHandle> {
/// \c rosa::Agent and \c rosa::MessagingSystem are our friends, they may
/// inspect the private member fields of the class.
///@{
friend class Agent;
friend class MessagingSystem;
///@}
/// The wrapped \c rosa::Agent instance.
Agent &A;
/// The \c rosa::MessagingSystem owning \c A.
MessagingSystem &S;
/// Creates a new instance without validating the state of the wrapped
/// \c rosa::Agent.
///
/// \note Used by a \c rosa::Agent instance to create a reference to itself
/// during construction, when its state is not valid yet.
///
/// \param A \c rosa::Agent to wrap
///
/// \note There a second argument, which is ignored, that is only present to
/// separate this constructor from the public constructor taking only a
/// \c rosa::Agent to wrap.
AgentHandle(Agent &A, bool) noexcept;
public:
/// Creates a new instance validating the state of the wrapped \p rosa::Agent.
///
/// \note The wrapped \c rosa::Agent must be in a valid state to instantiate
/// \c rosa::AgentHandle with this constructor.
///
/// \param A \c rosa::Agent to wrap
///
/// \pre \p A is registered in its owning *system*:\code
/// A.system().isUnitRegistered(A)
/// \endcode
AgentHandle(Agent &A);
/// Destroys \p this object.
///
/// The destructor has nothing to take care of.
~AgentHandle(void) = default;
/// Tells if the wrapped \c rosa::Agent is in a valid state.
///
/// \note A \c rosa::AgentHandler belongs to a \c rosa::MessagingSystem.
/// Working with a \c rosa::AgentHandler whose originating
/// \c rosa::MessagingSystem has already been destroyed results in *undefined*
/// behavior.
///
/// \return if the wrapped \c rosa::Agent is in a valid state
operator bool(void) const noexcept override;
/// Tells if another \c rosa::AgentHandle wraps the same \c rosa::Agent as
/// \p this object.
///
/// \param H \c rosa::AgentHandle whose wrapped \c rosa::Agent to check
///
/// \return if \p H wraps \c A like \p this object
bool operator==(const AgentHandle &H) const noexcept override;
/// Compares \p this object to another \c rosa::AgentHandle instance.
///
/// The comparison is based on the memory addresses of the wrapped
/// \c rosa::Agent instances.
///
/// \param H \c rosa::AgentHandle to compare to
///
/// \return if \p this object a \c rosa::Agent instance whose address is less
/// than that of \p H
bool operator<(const AgentHandle &H) const noexcept override;
/// Returns a reference to the wrapped \c rosa::Agent.
///
/// \return a reference to \c A
AgentHandle self(void) noexcept override;
/// Sends a given \c rosa::message_t instance to the wrapped \c rosa::Agent.
///
/// \param M message to send
///
/// \pre The wrapped \c rosa::Agent instance is in a valid state:\code
/// bool(*this)
/// \endcode
void sendMessage(message_t &&M) noexcept override;
};
/// Template specialization for optionally storing \c rosa::AgentHandle
/// instances.
///
/// \ingroup Optional
///
/// Due to \c rosa::AgentHandle not supporting copying and moving of instances,
/// the member functions in this class fall back to destroying the old stored
/// object and creating a new one whenever the stored value is to be changed.
template <> class Optional<AgentHandle> {
public:
using Type = AgentHandle;
/// 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.
///
/// \param X value to store in the object
Optional(AgentHandle 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 as a copy of another one.
///
/// \param Other the instance whose state to obtain
Optional(Optional &&Other) noexcept : 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) {
destroy();
}
if (Other.Valid) {
cr(Other.Value);
}
return *this;
}
/// Updates \p this object by copying the state of another one.
///
/// \param Other the instance whose state to obtain
///
/// \return reference of the updated instance
Optional &operator=(Optional &&Other) noexcept {
if (Valid) {
destroy();
}
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
AgentHandle &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 AgentHandle &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 AgentHandle *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
AgentHandle *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
AgentHandle &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 AgentHandle &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 AgentHandle &valueOr(const AgentHandle &DefaultValue) const {
return Valid ? Value : DefaultValue;
}
private:
/// Deallocates the stored value if any.
void destroy(void) {
if (Valid) {
Value.~AgentHandle();
Valid = false;
}
}
/// Updates the state of \p this object by copying a value into it.
///
/// \tparam V type of \p X
///
/// \param X value to copy
///
/// \pre \p this object does not contain a value
template <typename V> void cr(V &&X) {
ASSERT(!Valid);
Valid = true;
new (&Value) AgentHandle(std::forward<V>(X));
}
/// Denotes if \p this object contains a value.
bool Valid;
/// Holds the stored value if any.
union {
AgentHandle Value; ///< The stored value.
};
};
} // End namespace rosa
#endif // ROSA_CORE_AGENTHANDLE_HPP

File Metadata

Mime Type
text/x-c++
Expires
Sat, Jun 7, 5:09 PM (4 h, 33 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
150282
Default Alt Text
AgentHandle.hpp (8 KB)

Event Timeline