Commit df82f541 authored by Dominik Charousset's avatar Dominik Charousset

maintenance & documentation

parent 4a6eefe0
......@@ -129,7 +129,6 @@ cppa/stacked_event_based_actor.hpp
cppa/to_string.hpp
cppa/tpartial_function.hpp
cppa/tuple_cast.hpp
cppa/type_value_pair.hpp
cppa/uniform_type_info.hpp
cppa/util/abstract_uniform_type_info.hpp
cppa/util/apply_args.hpp
......
......@@ -47,6 +47,12 @@ namespace cppa {
class serializer;
class deserializer;
class actor;
/**
* @brief A unique actor ID.
* @relates actor
*/
typedef std::uint32_t actor_id;
/**
......@@ -216,6 +222,7 @@ class actor : public channel {
/**
* @brief A smart pointer type that manages instances of {@link actor}.
* @relates actor
*/
typedef intrusive_ptr<actor> actor_ptr;
......
......@@ -79,6 +79,9 @@ class actor_proxy : public abstract_actor<actor> {
#endif // CPPA_DOCUMENTATION
/**
* @brief A smart pointer to an {@link actor_proxy} instance.
*/
typedef intrusive_ptr<actor_proxy> actor_proxy_ptr;
} // namespace cppa
......
......@@ -111,32 +111,51 @@ bool announce(const std::type_info& tinfo, uniform_type_info* utype);
template<class C, class Parent, typename... Args>
std::pair<C Parent::*, util::abstract_uniform_type_info<C>*>
compound_member(C Parent::*c_ptr, const Args&... args) {
return { c_ptr, new detail::default_uniform_type_info_impl<C>(args...) };
return {c_ptr, new detail::default_uniform_type_info_impl<C>(args...)};
}
// deals with getter returning a mutable reference
/**
* @brief Creates meta informations for a non-trivial member accessed
* via a getter returning a mutable reference.
* @param getter Member function pointer to the getter.
* @param args "Sub-members" of @p c_ptr
* @see {@link announce_example_4.cpp announce example 4}
* @returns A pair of @p c_ptr and the created meta informations.
*/
template<class C, class Parent, typename... Args>
std::pair<C& (Parent::*)(), util::abstract_uniform_type_info<C>*>
compound_member(C& (Parent::*c_ptr)(), const Args&... args) {
return { c_ptr, new detail::default_uniform_type_info_impl<C>(args...) };
compound_member(C& (Parent::*getter)(), const Args&... args) {
return {getter, new detail::default_uniform_type_info_impl<C>(args...)};
}
// deals with getter/setter pair
/**
* @brief Creates meta informations for a non-trivial member accessed
* via a getter/setter pair.
* @param gspair A pair of two member function pointers representing
* getter and setter.
* @param args "Sub-members" of @p c_ptr
* @see {@link announce_example_4.cpp announce example 4}
* @returns A pair of @p c_ptr and the created meta informations.
*/
template<class Parent, typename GRes,
typename SRes, typename SArg, typename... Args>
std::pair<std::pair<GRes (Parent::*)() const, SRes (Parent::*)(SArg)>,
util::abstract_uniform_type_info<typename util::rm_ref<GRes>::type>*>
compound_member(const std::pair<GRes (Parent::*)() const, SRes (Parent::*)(SArg)>& gspair,
compound_member(const std::pair<GRes (Parent::*)() const,
SRes (Parent::*)(SArg) >& gspair,
const Args&... args) {
return { gspair, new detail::default_uniform_type_info_impl<typename util::rm_ref<GRes>::type>(args...) };
typedef typename util::rm_ref<GRes>::type mtype;
return {gspair, new detail::default_uniform_type_info_impl<mtype>(args...)};
}
/**
* @brief Adds a new type mapping for @p T to the libcppa type system.
* @param args Members of @p T.
* @returns @c true if @p T was added to the libcppa type system;
* otherwise @c false.
* @returns @c true if @p T was added to the libcppa type system,
* @c false otherwise.
*/
template<typename T, typename... Args>
inline bool announce(const Args&... args) {
......
......@@ -257,6 +257,10 @@ inline bool operator!=(const any_tuple& lhs, const any_tuple& rhs) {
return !(lhs == rhs);
}
/**
* @brief Creates an {@link any_tuple} containing the elements @p args.
* @param args Values to initialize the tuple elements.
*/
template<typename... Args>
inline any_tuple make_any_tuple(Args&&... args) {
return make_cow_tuple(std::forward<Args>(args)...);
......
......@@ -40,14 +40,23 @@ namespace cppa {
*/
struct anything { };
inline bool operator==(const anything&, const anything&) {
return true;
}
/**
* @brief Compares two instances of {@link anything}.
* @returns @p false
* @relates anything
*/
inline bool operator==(const anything&, const anything&) { return true; }
inline bool operator!=(const anything&, const anything&) {
return false;
}
/**
* @brief Compares two instances of {@link anything}.
* @returns @p false
* @relates anything
*/
inline bool operator!=(const anything&, const anything&) { return false; }
/**
* @brief Checks wheter @p T is {@link anything}.
*/
template<typename T>
struct is_anything {
static constexpr bool value = std::is_same<T, anything>::value;
......
......@@ -37,12 +37,22 @@
namespace cppa {
/**
* @brief The value type of atoms.
*/
enum class atom_value : std::uint64_t { dirty_little_hack = 37337 };
std::string to_string(const atom_value& a);
/**
* @brief Returns @p what as a string representation.
* @param what Compact representation of an atom.
* @returns @p what as string.
*/
std::string to_string(const atom_value& what);
/**
* @brief Creates an atom from given string literal.
* @param str String constant representing an atom.
* @returns A compact representation of @p str.
*/
template<size_t Size>
constexpr atom_value atom(char const (&str) [Size]) {
......
......@@ -53,7 +53,6 @@ class behavior {
friend behavior operator,(partial_function&& lhs, behavior&& rhs);
public:
behavior() = default;
......@@ -95,10 +94,11 @@ class behavior {
return m_fun(std::move(value));
}
private:
inline bool undefined() const {
return m_fun.undefined() && m_timeout.valid() == false;
}
// terminates recursion
inline behavior& splice() { return *this; }
private:
partial_function m_fun;
util::duration m_timeout;
......@@ -106,9 +106,13 @@ class behavior {
};
/**
* @brief Concatenates a match expression and a timeout specification
* represented by an rvalue behavior object.
*/
template<typename... Lhs>
behavior operator,(const match_expr<Lhs...>& lhs,
behavior&& rhs) {
behavior operator,(const match_expr<Lhs...>& lhs, behavior&& rhs) {
CPPA_REQUIRE(rhs.get_partial_function().undefined());
rhs.get_partial_function() = lhs;
return std::move(rhs);
}
......
......@@ -71,6 +71,7 @@ class channel : public ref_counted {
/**
* @brief A smart pointer type that manages instances of {@link channel}.
* @relates channel
*/
typedef intrusive_ptr<channel> channel_ptr;
......
......@@ -135,8 +135,9 @@
* @p libcppa uses a copy-on-write optimization for its message
* passing implementation.
*
* {@link cppa::tuple Tuples} should @b always be used with by-value semantic,
* since tuples use a copy-on-write smart pointer internally. Let's assume two
* {@link cppa::cow_tuple Tuples} should @b always be used with by-value
* semantic,since tuples use a copy-on-write smart pointer internally.
* Let's assume two
* tuple @p x and @p y, whereas @p y is a copy of @p x:
*
* @code
......@@ -425,33 +426,38 @@ namespace cppa {
/**
* @ingroup ActorManagement
* @brief Spans a new context-switching actor.
* @returns A pointer to the spawned {@link actor Actor}.
* @brief Spawns a new context-switching actor.
* @param whom Instance of an event-based actor.
* @returns An {@link actor_ptr} to the spawned {@link actor}.
*/
inline actor_ptr spawn(scheduled_actor* what) {
return get_scheduler()->spawn(what);
inline actor_ptr spawn(scheduled_actor* whom) {
return get_scheduler()->spawn(whom);
}
/**
* @ingroup ActorManagement
* @brief Spans a new context-switching actor.
* @tparam Hint Hint to the scheduler for the best scheduling strategy.
* @returns A pointer to the spawned {@link actor Actor}.
* @brief Spawns a new context-switching actor.
* @tparam Hint A hint to the scheduler for the best scheduling strategy.
* @param bhvr A function implementing the actor's behavior.
* @returns An {@link actor_ptr} to the spawned {@link actor}.
*/
template<scheduling_hint Hint>
inline actor_ptr spawn(std::function<void()> what) {
return get_scheduler()->spawn(std::move(what), Hint);
inline actor_ptr spawn(std::function<void()> bhvr) {
return get_scheduler()->spawn(std::move(bhvr), Hint);
}
/**
* @ingroup ActorManagement
* @brief Spans a new event-based actor.
* @returns A pointer to the spawned {@link actor Actor}.
* @brief Spawns a new context-switching actor,
* equal to <tt>spawn<detached>(bhvr)</tt>.
* @param bhvr A function implementing the actor's behavior.
* @returns An {@link actor_ptr} to the spawned {@link actor}.
*/
inline actor_ptr spawn(std::function<void()> what) {
return get_scheduler()->spawn(std::move(what), scheduled);
inline actor_ptr spawn(std::function<void()> bhvr) {
return get_scheduler()->spawn(std::move(bhvr), scheduled);
}
// forwards self_type as actor_ptr
template<typename T>
struct spawn_fwd_ {
static inline T&& _(T&& arg) { return std::move(arg); }
......@@ -464,28 +470,50 @@ struct spawn_fwd_<self_type> {
static inline actor_ptr _(const self_type&) { return self; }
};
template<typename F, typename Arg0, typename... Args>
inline actor_ptr spawn(F&& what, Arg0&& arg0, Args&&... args) {
return spawn(std::bind(std::move(what),
spawn_fwd_<typename util::rm_ref<Arg0>::type>::_(arg0),
spawn_fwd_<typename util::rm_ref<Args>::type>::_(args)...));
}
/**
* @ingroup ActorManagement
* @brief Spawns a new context-switching actor that executes
* <tt>bhvr(arg0, args...)</tt>.
* @tparam Hint A hint to the scheduler for the best scheduling strategy.
* @param bhvr A functor implementing the actor's behavior.
* @param arg0 First argument to @p bhvr.
* @param args Further argumetns to @p bhvr.
* @returns An {@link actor_ptr} to the spawned {@link actor}.
*/
template<scheduling_hint Hint, typename F, typename Arg0, typename... Args>
inline actor_ptr spawn(F&& what, Arg0&& arg0, Args&&... args) {
return spawn<Hint>(std::bind(std::move(what),
inline actor_ptr spawn(F bhvr, Arg0&& arg0, Args&&... args) {
return spawn<Hint>(std::bind(std::move(bhvr),
spawn_fwd_<typename util::rm_ref<Arg0>::type>::_(arg0),
spawn_fwd_<typename util::rm_ref<Args>::type>::_(args)...));
}
/**
* @ingroup ActorManagement
* @brief Spawns a new context-switching actor that executes
* <tt>bhvr(arg0, args...)</tt>, equal to
* <tt>spawn<scheduled>(bhvr, arg0, args...)</tt>.
* @param bhvr A functor implementing the actor's behavior.
* @param arg0 First argument to @p bhvr.
* @param args Further argumetns to @p bhvr.
* @returns An {@link actor_ptr} to the spawned {@link actor}.
*/
template<typename F, typename Arg0, typename... Args>
inline actor_ptr spawn(F&& bhvr, Arg0&& arg0, Args&&... args) {
return spawn<scheduled>(std::forward<F>(bhvr),
std::forward<Arg0>(arg0),
std::forward<Args>(args)...);
}
#ifdef CPPA_DOCUMENTATION
/**
* @ingroup MessageHandling
* @brief Sends <tt>{arg0, args...}</tt> as a message to @p whom.
* @brief Sends <tt>{what...}</tt> as a message to @p whom.
* @param whom Receiver of the message.
* @param what Message elements.
*/
template<typename Arg0, typename... Args>
void send(channel_ptr& whom, const Arg0& arg0, const Args&... args);
template<typename... Args>
void send(channel_ptr& whom, const Args&... what);
/**
* @ingroup MessageHandling
......@@ -493,8 +521,10 @@ void send(channel_ptr& whom, const Arg0& arg0, const Args&... args);
*
* <b>Usage example:</b>
* @code
* self << make_cow_tuple(1, 2, 3);
* self << make_any_tuple(1, 2, 3);
* @endcode
* @param whom Receiver of the message.
* @param what Message as instance of {@link any_tuple}.
* @returns @p whom.
*/
channel_ptr& operator<<(channel_ptr& whom, const any_tuple& what);
......@@ -579,52 +609,57 @@ const self_type& operator<<(const self_type& s, any_tuple&& what);
/**
* @ingroup MessageHandling
* @brief Sends a message to the sender of the last received message.
* @param what Message elements.
*/
template<typename Arg0, typename... Args>
inline void reply(const Arg0& arg0, const Args&... args) {
send(self->last_sender(), arg0, args...);
template<typename... Args>
inline void reply(const Args&... what) {
send(self->last_sender(), what...);
}
/**
* @ingroup MessageHandling
* @brief Sends a message to @p whom that is delayed by @p rel_time.
* @param whom Receiver of the message.
* @param rel_time Relative time duration to delay the message.
* @param data Any number of values for the message content.
* @param rel_time Relative time duration to delay the message in
* microseconds, milliseconds, seconds or minutes.
* @param what Message elements.
*/
template<class Rep, class Period, typename... Data>
template<class Rep, class Period, typename... Args>
inline void delayed_send(actor_ptr whom,
const std::chrono::duration<Rep, Period>& rel_time,
const Data&... data) {
get_scheduler()->delayed_send(whom, rel_time, data...);
const Args&... what) {
get_scheduler()->delayed_send(whom, rel_time, what...);
}
/**
* @ingroup MessageHandling
* @brief Sends a reply message that is delayed by @p rel_time.
* @param rel_time Relative time duration to delay the message in
* microseconds, milliseconds, seconds or minutes.
* @param what Message elements.
* @see delayed_send()
*/
template<class Rep, class Period, typename... Data>
template<class Rep, class Period, typename... Args>
inline void delayed_reply(const std::chrono::duration<Rep, Period>& rel_time,
const Data&... data) {
delayed_send(self->last_sender(), rel_time, data...);
const Args&... what) {
delayed_send(self->last_sender(), rel_time, what...);
}
/**
* @brief Blocks execution of this actor until all
* other actors finished execution.
* @warning This function will cause a deadlock if
* called from multiple actors.
* @warning This function will cause a deadlock if called from multiple actors.
* @warning Do not call this function in cooperatively scheduled actors.
*/
inline void await_all_others_done() {
detail::actor_count_wait_until((self.unchecked() == nullptr) ? 0 : 1);
}
/**
* @brief Publishes @p whom at given @p port.
* @brief Publishes @p whom at @p port.
*
* The connection is automatically closed if the lifetime of @p whom ends.
* @param whom Actor that should be published at given @p port.
* @param whom Actor that should be published at @p port.
* @param port Unused TCP port.
* @throws bind_failure
*/
......@@ -634,7 +669,8 @@ void publish(actor_ptr whom, std::uint16_t port);
* @brief Establish a new connection to the actor at @p host on given @p port.
* @param host Valid hostname or IP address.
* @param port TCP port.
* @returns A pointer to the proxy instance that represents the remote Actor.
* @returns An {@link actor_ptr} to the proxy instance
* representing a remote actor.
*/
actor_ptr remote_actor(const char* host, std::uint16_t port);
......
......@@ -110,7 +110,14 @@ class deserializer {
};
deserializer& operator>>(deserializer& d, object& what);
/**
* @brief Deserializes a value and stores the result in @p storage.
* @param d A valid deserializer.
* @param storage An that should contain the deserialized value.
* @returns @p d
* @relates deserializer
*/
deserializer& operator>>(deserializer& d, object& storage);
} // namespace cppa
......
......@@ -34,7 +34,6 @@
#include <vector>
#include "cppa/object.hpp"
#include "cppa/type_value_pair.hpp"
#include "cppa/detail/abstract_tuple.hpp"
namespace cppa { namespace detail {
......
......@@ -33,7 +33,6 @@
#include "cppa/pattern.hpp"
#include "cppa/any_tuple.hpp"
#include "cppa/type_value_pair.hpp"
#include "cppa/detail/matches.hpp"
#include "cppa/detail/tuple_vals.hpp"
......
......@@ -33,8 +33,6 @@
#include <stdexcept>
#include "cppa/type_value_pair.hpp"
#include "cppa/util/type_list.hpp"
#include "cppa/detail/tdata.hpp"
......
......@@ -3,8 +3,6 @@
#include <typeinfo>
#include "cppa/type_value_pair.hpp"
#include "cppa/util/type_list.hpp"
#include "cppa/util/is_builtin.hpp"
......
......@@ -40,14 +40,27 @@
namespace cppa {
/**
* @brief Converts a string created by {@link cppa::to_string to_string}
* to its original value.
* @param what String representation of a serialized value.
* @returns An {@link cppa::object object} instance that contains
* the deserialized value.
*/
object from_string(const std::string& what);
/**
* @brief Convenience function that deserializes a value from @p what and
* converts the result to @p T.
* @throws std::logic_error if the result is not of type @p T.
* @returns The deserialized value as instance of @p T.
*/
template<typename T>
T from_string(const std::string &what) {
T from_string(const std::string& what) {
object o = from_string(what);
const std::type_info& tinfo = typeid(T);
if (tinfo == *(o.type())) {
return std::move(get<T>(o));
return std::move(get_ref<T>(o));
}
else {
std::string error_msg = "expected type name ";
......
......@@ -31,6 +31,9 @@
#ifndef GET_HPP
#define GET_HPP
// functions are documented in the implementation headers
#ifndef CPPA_DOCUMENTATION
#include <cstddef>
#include "cppa/util/at.hpp"
......@@ -79,4 +82,5 @@ typename util::at<N, Ts...>::type get(const util::type_list<Ts...>&) {
} // namespace cppa
#endif // CPPA_DOCUMENTATION
#endif // GET_HPP
......@@ -166,6 +166,7 @@ class group : public channel {
/**
* @brief A smart pointer type that manages instances of {@link group}.
* @relates group
*/
typedef intrusive_ptr<group> group_ptr;
......
......@@ -156,7 +156,7 @@ struct ge_reference_wrapper<bool> {
};
/**
* @brief Create a reference wrapper similar to std::reference_wrapper<const T>
* @brief Creates a reference wrapper similar to std::reference_wrapper<const T>
* that could be used in guard expressions or to enforce lazy evaluation.
*/
template<typename T>
......
......@@ -42,8 +42,7 @@ namespace cppa {
template<class From, class To>
struct convertible {
constexpr convertible() { }
To convert() const {
inline To convert() const {
return static_cast<const From*>(this)->do_convert();
}
};
......@@ -54,14 +53,7 @@ struct convertible {
*/
template<typename T>
class intrusive_ptr : util::comparable<intrusive_ptr<T>, const T*>,
util::comparable<intrusive_ptr<T>> {
T* m_ptr;
inline void set_ptr(T* raw_ptr) {
m_ptr = raw_ptr;
if (raw_ptr) raw_ptr->ref();
}
util::comparable<intrusive_ptr<T> > {
public:
......@@ -71,7 +63,7 @@ class intrusive_ptr : util::comparable<intrusive_ptr<T>, const T*>,
intrusive_ptr(const intrusive_ptr& other) { set_ptr(other.m_ptr); }
intrusive_ptr(intrusive_ptr&& other) : m_ptr(other.take()) { }
intrusive_ptr(intrusive_ptr&& other) : m_ptr(other.release()) { }
// enables "actor_ptr s = self"
template<typename From>
......@@ -87,7 +79,7 @@ class intrusive_ptr : util::comparable<intrusive_ptr<T>, const T*>,
}
template<typename Y>
intrusive_ptr(intrusive_ptr<Y>&& other) : m_ptr(other.take()) {
intrusive_ptr(intrusive_ptr<Y>&& other) : m_ptr(other.release()) {
static_assert(std::is_convertible<Y*, T*>::value,
"Y* is not assignable to T*");
}
......@@ -102,7 +94,7 @@ class intrusive_ptr : util::comparable<intrusive_ptr<T>, const T*>,
inline const T* get() const { return m_ptr; }
T* take() {
T* release() {
auto result = m_ptr;
m_ptr = nullptr;
return result;
......@@ -154,7 +146,7 @@ class intrusive_ptr : util::comparable<intrusive_ptr<T>, const T*>,
static_assert(std::is_convertible<Y*, T*>::value,
"Y* is not assignable to T*");
reset();
m_ptr = other.take();
m_ptr = other.release();
return *this;
}
......@@ -186,23 +178,60 @@ class intrusive_ptr : util::comparable<intrusive_ptr<T>, const T*>,
return (m_ptr) ? static_cast<C*>(const_cast<T*>(m_ptr)) : nullptr;
}
private:
T* m_ptr;
inline void set_ptr(T* raw_ptr) {
m_ptr = raw_ptr;
if (raw_ptr) raw_ptr->ref();
}
};
/**
* @relates intrusive_ptr
*/
template<typename X>
inline bool operator==(const intrusive_ptr<X>& lhs, decltype(nullptr)) {
return lhs.get() == nullptr;
inline bool operator==(const intrusive_ptr<X>& ptr, decltype(nullptr)) {
return ptr.get() == nullptr;
}
/**
* @relates intrusive_ptr
*/
template<typename X>
inline bool operator==(decltype(nullptr), const intrusive_ptr<X>& ptr) {
return ptr.get() == nullptr;
}
/**
* @relates intrusive_ptr
*/
template<typename X>
inline bool operator!=(const intrusive_ptr<X>& lhs, decltype(nullptr)) {
return lhs.get() != nullptr;
}
/**
* @relates intrusive_ptr
*/
template<typename X>
inline bool operator==(decltype(nullptr), const intrusive_ptr<X>& rhs) {
return rhs.get() == nullptr;
inline bool operator!=(decltype(nullptr), const intrusive_ptr<X>& rhs) {
return rhs.get() != nullptr;
}
/**
* @relates intrusive_ptr
*/
template<typename X, typename Y>
bool operator==(const intrusive_ptr<X>& lhs, const intrusive_ptr<Y>& rhs) {
inline bool operator==(const intrusive_ptr<X>& lhs, const intrusive_ptr<Y>& rhs) {
return lhs.get() == rhs.get();
}
/**
* @relates intrusive_ptr
*/
template<typename X, typename Y>
inline bool operator!=(const intrusive_ptr<X>& lhs, const intrusive_ptr<Y>& rhs) {
return !(lhs == rhs);
......
......@@ -140,7 +140,8 @@ class local_actor : public actor {
/**
* @ingroup ActorManagement
* @brief Adds a unidirectional @p monitor to @p whom.
* @note Each calls to @p monitor creates a new, independent monitor.
* @param whom The actor that should be monitored by this actor.
* @note Each call to @p monitor creates a new, independent monitor.
* @pre The calling actor receives a "DOWN" message from @p whom when
* it terminates.
*/
......@@ -149,11 +150,16 @@ class local_actor : public actor {
/**
* @ingroup ActorManagement
* @brief Removes a monitor from @p whom.
* @param whom A monitored actor.
*/
void demonitor(actor_ptr whom);
};
/**
* @brief A smart pointer to a {@link local_actor} instance.
* @relates local_actor
*/
typedef intrusive_ptr<local_actor> local_actor_ptr;
} // namespace cppa
......
......@@ -123,12 +123,17 @@ struct pmatch_each_helper {
namespace cppa {
inline detail::match_helper match(any_tuple t) {
return std::move(t);
/**
* @brief Starts a match expression.
* @param what Tuple or value that should be matched against a pattern.
* @returns A helper object providing <tt>operator(...)</tt>.
*/
inline detail::match_helper match(any_tuple what) {
return std::move(what);
}
/**
* @brief Match expression.
* @copydoc match(any_tuple)
*/
template<typename T>
detail::match_helper match(T&& what) {
......@@ -136,7 +141,9 @@ detail::match_helper match(T&& what) {
}
/**
* @brief Match expression that matches against all elements of @p what.
* @brief Starts a match expression that matches each element of @p what.
* @param what An STL-compliant container.
* @returns A helper object providing <tt>operator(...)</tt>.
*/
template<class Container>
auto match_each(Container& what)
......@@ -144,21 +151,41 @@ auto match_each(Container& what)
return {std::begin(what), std::end(what)};
}
/**
* @brief Starts a match expression that matches each element of @p what.
* @param what An STL-compliant container.
* @returns A helper object providing <tt>operator(...)</tt>.
*/
template<typename T>
auto match_each(std::initializer_list<T> list)
auto match_each(std::initializer_list<T> what)
-> detail::copying_match_each_helper<std::vector<typename detail::strip_and_convert<T>::type>> {
std::vector<typename detail::strip_and_convert<T>::type> vec;
vec.reserve(list.size());
for (auto& i : list) vec.emplace_back(std::move(i));
vec.reserve(what.size());
for (auto& i : what) vec.emplace_back(std::move(i));
return vec;
}
/**
* @brief Starts a match expression that matches each element in
* range [first, last).
* @param first Iterator to the first element.
* @param last Iterator to the last element (excluded).
* @returns A helper object providing <tt>operator(...)</tt>.
*/
template<typename InputIterator>
auto match_each(InputIterator first, InputIterator last)
-> detail::match_each_helper<InputIterator> {
return {first, last};
}
/**
* @brief Starts a match expression that matches <tt>proj(i)</tt> for
* each element @p i in range [first, last).
* @param first Iterator to the first element.
* @param last Iterator to the last element (excluded).
* @param proj Projection or extractor functor.
* @returns A helper object providing <tt>operator(...)</tt>.
*/
template<typename InputIterator, typename Projection>
auto match_each(InputIterator first, InputIterator last, Projection proj)
-> detail::pmatch_each_helper<InputIterator, Projection> {
......
......@@ -44,6 +44,10 @@ namespace cppa {
// forward declarations
class object;
/**
* @relates object
*/
bool operator==(const object& lhs, const object& rhs);
class uniform_type_info;
......
......@@ -86,14 +86,16 @@ class partial_function {
return (*this)(cpy);
}
inline bool undefined() const {
return m_impl == nullptr;
}
private:
impl_ptr m_impl;
};
//behavior operator,(partial_function&& lhs, behavior&& rhs);
} // namespace cppa
#endif // PARTIAL_FUNCTION_HPP
......@@ -42,7 +42,6 @@
#include "cppa/option.hpp"
#include "cppa/anything.hpp"
#include "cppa/any_tuple.hpp"
#include "cppa/type_value_pair.hpp"
#include "cppa/uniform_type_info.hpp"
#include "cppa/util/guard.hpp"
......@@ -59,6 +58,10 @@
namespace cppa {
/**
* @brief Denotes the position of {@link cppa::anything anything} in a
* template parameter pack.
*/
enum class wildcard_position {
nil,
trailing,
......@@ -67,6 +70,11 @@ enum class wildcard_position {
multiple
};
/**
* @brief Gets the position of {@link cppa::anything anything} from the
* type list @p Types.
* @tparam A template parameter pack as {@link cppa::util::type_list type_list}.
*/
template<typename Types>
constexpr wildcard_position get_wildcard_position() {
return util::tl_exists<Types, is_anything>::value
......@@ -215,6 +223,9 @@ class value_matcher_impl<wildcard_position::multiple,
};
/**
* @brief A pattern matching for type and optionally value of tuple elements.
*/
template<typename... Types>
class pattern {
......@@ -230,6 +241,9 @@ class pattern {
static constexpr wildcard_position wildcard_pos =
get_wildcard_position<util::type_list<Types...> >();
/**
* @brief Parameter pack as {@link cppa::util::type_list type_list}.
*/
typedef util::type_list<Types...> types;
typedef typename types::head head_type;
......@@ -312,23 +326,6 @@ class pattern {
private:
typedef type_value_pair tvp_array[size];
// a polymophic functor
struct init_helper {
size_t i;
tvp_array& m_ptrs;
detail::types_array<Types...>& m_arr;
init_helper(tvp_array& ptrs, detail::types_array<Types...>& tarr)
: i(0), m_ptrs(ptrs), m_arr(tarr) { }
template<typename T>
inline void operator()(const option<T>& what) {
m_ptrs[i].first = m_arr[i];
m_ptrs[i].second = (what) ? &(*what) : nullptr;
++i;
}
};
std::unique_ptr<value_matcher> m_vm;
};
......
......@@ -35,10 +35,11 @@ namespace cppa {
/**
* @ingroup TypeSystem
* @brief Represents a type flag of {@link primitive_variant}.
* @brief Represents the type flag of
* {@link cppa::primitive_variant primitive_variant}.
*
* Includes integers (signed and unsigned), floating points
* and unicode strings (std::string, std::u16string and std::u32string).
* and strings (std::string, std::u16string and std::u32string).
* @relates primitive_variant
*/
enum primitive_type {
......
......@@ -335,13 +335,47 @@ get_ref(primitive_variant& pv) {
#endif
/**
* @relates primitive_variant
*/
bool operator==(const primitive_variant& lhs, const primitive_variant& rhs);
inline
bool operator!=(const primitive_variant& lhs, const primitive_variant& rhs) {
/**
* @relates primitive_variant
*/
inline bool operator!=(const primitive_variant& lhs, const primitive_variant& rhs) {
return !(lhs == rhs);
}
#ifndef CPPA_DOCUMENTATION
/**
* @relates primitive_variant
*/
template<typename T>
bool operator==(const T& lhs, const primitive_variant& rhs);
/**
* @relates primitive_variant
*/
template<typename T>
bool operator==(const primitive_variant& lhs, const T& rhs);
/**
* @relates primitive_variant
*/
template<typename T>
bool operator!=(const T& lhs, const primitive_variant& rhs);
/**
* @relates primitive_variant
*/
template<typename T>
bool operator!=(const primitive_variant& lhs, const T& rhs);
#else
template<typename T>
typename std::enable_if<util::is_primitive<T>::value, bool>::type
operator==(const T& lhs, const primitive_variant& rhs) {
......@@ -368,6 +402,8 @@ operator!=(const T& lhs, const primitive_variant& rhs) {
return !(lhs == rhs);
}
#endif // CPPA_DOCUMENTATION
} // namespace cppa
namespace cppa { namespace detail {
......@@ -387,7 +423,7 @@ void ptv_set(primitive_type& lhs_type, T& lhs, V&& rhs,
template<primitive_type FT, class T, class V>
void ptv_set(primitive_type& lhs_type, T& lhs, V&& rhs,
typename std::enable_if<std::is_arithmetic<T>::value, int>::type*) {
// don't call a constructor for arithmetic types
// never call constructors for arithmetic types
lhs = rhs;
lhs_type = FT;
}
......
......@@ -120,6 +120,9 @@ inline bool equal(const process_information::node_id_type& node_id,
return equal(hash, node_id);
}
/**
* @relates process_information
*/
std::string to_string(const process_information& what);
/**
......@@ -127,12 +130,14 @@ std::string to_string(const process_information& what);
* to a hexadecimal string.
* @param node_id A unique node identifier.
* @returns A hexadecimal representation of @p node_id.
* @relates process_information
*/
std::string to_string(const process_information::node_id_type& node_id);
/**
* @brief A smart pointer type that manages instances of
* {@link process_information}.
* @relates process_information
*/
typedef intrusive_ptr<process_information> process_information_ptr;
......
......@@ -94,6 +94,13 @@ class serializer {
};
/**
* @brief Serializes a value to @p s.
* @param s A valid serializer.
* @param what A value of an announced or primitive type.
* @returns @p s
* @relates serializer
*/
template<typename T>
serializer& operator<<(serializer& s, const T& what) {
auto mtype = uniform_typeid<T>();
......
......@@ -41,27 +41,86 @@
namespace cppa {
#ifdef CPPA_DOCUMENTATION
/**
* @brief Tries to cast @p tup to {@link cow_tuple cow_tuple<T...>} and moves
* the content of @p tup to the returned tuple on success.
* @param tup Dynamically typed tuple.
* @param pttrn Requested types with optional guard values.
* @returns An {@link option} for a {@link cow_tuple} with the types
* deduced from @p pttrn.
* @relates any_tuple
*/
auto moving_tuple_cast(any_tuple& tup, const pattern<T...>& pttrn);
/**
* @brief Tries to cast @p tup to {@link cow_tuple cow_tuple<T...>} and moves
* the content of @p tup to the returned tuple on success.
* @param tup Dynamically typed tuple.
* @returns An {@link option} for a {@link cow_tuple} with the types
* deduced from {T...}.
* @relates any_tuple
*/
template<typename... T>
auto moving_tuple_cast(any_tuple& tup);
/**
* @brief Tries to cast @p tup to {@link cow_tuple cow_tuple<T...>} and moves
* the content of @p tup to the returned tuple on success.
* @param tup Dynamically typed tuple.
* @returns An {@link option} for a {@link cow_tuple} with the types
* deduced from {T...}.
* @relates any_tuple
*/
template<typename... T>
auto moving_tuple_cast(any_tuple& tup, const util::type_list<T...>&);
/**
* @brief Tries to cast @p tup to {@link cow_tuple cow_tuple<T...>}.
* @param tup Dynamically typed tuple.
* @param pttrn Requested types with optional guard values.
* @returns An {@link option} for a {@link cow_tuple} with the types
* deduced from @p pttrn.
* @relates any_tuple
*/
template<typename... T>
auto tuple_cast(any_tuple tup, const pattern<T...>& pttrn);
/**
* @brief Tries to cast @p tup to {@link tuple tuple<T...>}; moves content
* of @p tup on success.
* @brief Tries to cast @p tup to {@link cow_tuple cow_tuple<T...>}.
* @param tup Dynamically typed tuple.
* @returns An {@link option} for a {@link cow_tuple} with the types
* deduced from {T...}.
* @relates any_tuple
*/
template<typename... T>
auto moving_tuple_cast(any_tuple& tup, const pattern<T...>& p)
auto tuple_cast(any_tuple tup);
/**
* @brief Tries to cast @p tup to {@link cow_tuple cow_tuple<T...>}.
* @param tup Dynamically typed tuple.
* @returns An {@link option} for a {@link cow_tuple} with the types
* deduced from {T...}.
* @relates any_tuple
*/
template<typename... T>
auto tuple_cast(any_tuple tup, const util::type_list<T...>&);
#else
template<typename... T>
auto moving_tuple_cast(any_tuple& tup, const pattern<T...>& pttrn)
-> option<
typename cow_tuple_from_type_list<
typename pattern<T...>::filtered_types
>::type> {
typedef typename pattern<T...>::filtered_types filtered_types;
typedef typename cow_tuple_from_type_list<filtered_types>::type tuple_type;
static constexpr auto impl =
get_wildcard_position<util::type_list<T...>>();
return detail::tuple_cast_impl<impl, tuple_type, T...>::safe(tup, p);
static constexpr auto impl = get_wildcard_position<util::type_list<T...>>();
return detail::tuple_cast_impl<impl, tuple_type, T...>::safe(tup, pttrn);
}
/**
* @brief Tries to cast @p tup to {@link tuple tuple<T...>}; moves content
* of @p tup on success.
*/
template<typename... T>
auto moving_tuple_cast(any_tuple& tup)
-> option<
......@@ -82,21 +141,15 @@ auto moving_tuple_cast(any_tuple& tup, const util::type_list<T...>&)
return moving_tuple_cast<T...>(tup);
}
/**
* @brief Tries to cast @p tup to {@link tuple tuple<T...>}.
*/
template<typename... T>
auto tuple_cast(any_tuple tup, const pattern<T...>& p)
auto tuple_cast(any_tuple tup, const pattern<T...>& pttrn)
-> option<
typename cow_tuple_from_type_list<
typename pattern<T...>::filtered_types
>::type> {
return moving_tuple_cast(tup, p);
return moving_tuple_cast(tup, pttrn);
}
/**
* @brief Tries to cast @p tup to {@link tuple tuple<T...>}.
*/
template<typename... T>
auto tuple_cast(any_tuple tup)
-> option<
......@@ -113,7 +166,7 @@ auto tuple_cast(any_tuple tup, const util::type_list<T...>&)
return moving_tuple_cast<T...>(tup);
}
/////////////////////////// for in-library use only! ///////////////////////////
// ************************ for in-library use only! ************************ //
// (moving) cast using a pattern; does not perform type checking
template<typename... T>
......@@ -148,6 +201,7 @@ auto forced_tuple_cast(any_tuple& tup, const pattern<T...>& p)
return detail::tuple_cast_impl<impl, tuple_type, T...>::force(tup, p);
}
#endif // CPPA_DOCUMENTATION
} // namespace cppa
......
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_ *
* /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\ *
* \/____/ \/_/\/___/ \/____/ \ \ \/ \ \ \/ \/__/\/_/ *
* \ \_\ \ \_\ *
* \/_/ \/_/ *
* *
* Copyright (C) 2011, 2012 *
* Dominik Charousset <dominik.charousset@haw-hamburg.de> *
* *
* This file is part of libcppa. *
* libcppa is free software: you can redistribute it and/or modify it under *
* the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation, either version 3 of the License *
* or (at your option) any later version. *
* *
* libcppa is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* See the GNU Lesser General Public License for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with libcppa. If not, see <http://www.gnu.org/licenses/>. *
\******************************************************************************/
#ifndef TYPE_VALUE_PAIR_HPP
#define TYPE_VALUE_PAIR_HPP
#include <cstddef>
#include "cppa/uniform_type_info.hpp"
namespace cppa {
typedef std::pair<const uniform_type_info*, const void*> type_value_pair;
class type_value_pair_const_iterator {
const type_value_pair* iter;
public:
typedef type_value_pair const value_type;
typedef std::ptrdiff_t difference_type;
typedef const type_value_pair* pointer;
typedef const type_value_pair& reference;
typedef std::bidirectional_iterator_tag iterator_category;
constexpr type_value_pair_const_iterator() : iter(nullptr) { }
type_value_pair_const_iterator(const type_value_pair* i) : iter(i) { }
type_value_pair_const_iterator(const type_value_pair_const_iterator&)
= default;
type_value_pair_const_iterator&
operator=(const type_value_pair_const_iterator&) = default;
inline const uniform_type_info* type() const { return iter->first; }
inline const void* value() const { return iter->second; }
inline decltype(iter) base() const { return iter; }
inline decltype(iter) operator->() const { return iter; }
inline decltype(*iter) operator*() const { return *iter; }
inline type_value_pair_const_iterator& operator++() {
++iter;
return *this;
}
inline type_value_pair_const_iterator operator++(int) {
type_value_pair_const_iterator tmp{*this};
++iter;
return tmp;
}
inline type_value_pair_const_iterator& operator--() {
--iter;
return *this;
}
inline type_value_pair_const_iterator operator--(int) {
type_value_pair_const_iterator tmp{*this};
--iter;
return tmp;
}
inline type_value_pair_const_iterator operator+(size_t offset) {
return iter + offset;
}
inline type_value_pair_const_iterator& operator+=(size_t offset) {
iter += offset;
return *this;
}
};
/**
* @relates type_value_pair_const_iterator
*/
inline bool operator==(const type_value_pair_const_iterator& lhs,
const type_value_pair_const_iterator& rhs) {
return lhs.base() == rhs.base();
}
/**
* @relates type_value_pair_const_iterator
*/
inline bool operator!=(const type_value_pair_const_iterator& lhs,
const type_value_pair_const_iterator& rhs) {
return !(lhs == rhs);
}
} // namespace cppa
#endif // TYPE_VALUE_PAIR_HPP
......@@ -71,23 +71,20 @@ class duration {
public:
constexpr duration() : unit(time_unit::none), count(0) {
}
constexpr duration() : unit(time_unit::none), count(0) { }
constexpr duration(time_unit tu, std::uint32_t val) : unit(tu), count(val) {
}
constexpr duration(time_unit u, std::uint32_t v) : unit(u), count(v) { }
template<class Rep, class Period>
constexpr duration(std::chrono::duration<Rep, Period> d)
: unit(get_time_unit_from_period<Period>()), count(d.count()) {
: unit(get_time_unit_from_period<Period>()), count(d.count()) {
static_assert(get_time_unit_from_period<Period>() != time_unit::none,
"only seconds, milliseconds or microseconds allowed");
}
template<class Rep>
constexpr duration(std::chrono::duration<Rep, std::ratio<60,1> > d)
: unit(time_unit::seconds), count(d.count() * 60) {
}
: unit(time_unit::seconds), count(d.count() * 60) { }
/**
* @brief Returns true if <tt>unit != time_unit::none</tt>.
......
......@@ -44,8 +44,8 @@ namespace cppa { namespace util {
/**
* @brief A vector with a fixed maximum size.
*
* This implementation is highly optimized for arithmetic types and refuses
* any non-arithmetic template parameter.
* This implementation is highly optimized for arithmetic types and does
* <b>not</b> call constructors or destructors properly.
*/
template<typename T, size_t MaxSize>
class fixed_vector {
......@@ -73,7 +73,7 @@ class fixed_vector {
typedef std::reverse_iterator<iterator> reverse_iterator;
typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
constexpr fixed_vector() : m_size(0) { }
inline fixed_vector() : m_size(0) { }
fixed_vector(const fixed_vector& other) : m_size(other.m_size) {
std::copy(other.begin(), other.end(), begin());
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment