Commit e39d7161 authored by neverlord's avatar neverlord

documentation

parent b954a872
......@@ -47,6 +47,8 @@ class any_tuple
public:
typedef detail::abstract_tuple::const_iterator const_iterator;
/**
* @brief Creates an empty tuple.
*/
......@@ -131,8 +133,6 @@ class any_tuple
return *reinterpret_cast<T*>(mutable_at(p));
}
typedef detail::abstract_tuple::const_iterator const_iterator;
inline const_iterator begin() const { return m_vals->begin(); }
inline const_iterator end() const { return m_vals->end(); }
......
......@@ -41,6 +41,9 @@ enum class atom_value : std::uint64_t { dirty_little_hack = 37337 };
std::string to_string(atom_value const& a);
/**
* @brief Creates an atom from given string literal.
*/
template<size_t Size>
constexpr atom_value atom(char const (&str) [Size])
{
......
......@@ -44,7 +44,7 @@
namespace cppa {
/**
* @brief
* @brief Describes the behavior of an actor.
*/
class behavior
{
......
......@@ -87,10 +87,6 @@
* {@link MessageHandling message handling}
* section of this documentation.
*
* @subsection IntroHelloWorld Hello World Example
*
* @include hello_world_example.cpp
*
* @section GettingStarted Getting Started
*
* To build @p libcppa, you need <tt>GCC >= 4.6</tt>, @p Automake
......@@ -110,6 +106,18 @@
* Windows is not supported yet, because MVSC++ doesn't implement the
* C++11 features needed to compile @p libcppa.
*
* @section IntroHelloWorld Hello World Example
*
* @include hello_world_example.cpp
*
* @section IntroMoreExamples More Examples
*
* The {@link math_actor_example.cpp Math Actor Example} shows the usage
* of {@link receive_loop} and {@link cppa::arg_match arg_match}.
* The {@link dining_philosophers.cpp Dining Philosophers Example}
* introduces event-based actors and includes a lot of <tt>libcppa</tt>
* features.
*
* @namespace cppa
* @brief This is the root namespace of libcppa.
*
......@@ -120,10 +128,8 @@
* @brief This namespace contains utility classes and meta programming
* utilities used by the libcppa implementation.
*
* @namespace cppa::detail
* @brief This namespace contains implementation details. Classes and
* functions of this namespace could change even in minor
* updates of the library and should not be used by outside of libcppa.
* @namespace cppa::intrusive
* @brief This namespace contains intrusive container implementations.
*
* @defgroup CopyOnWrite Copy-on-write optimization.
* @p libcppa uses a copy-on-write optimization for its message
......
......@@ -39,6 +39,9 @@
namespace cppa {
/**
* @example dining_philosophers.cpp
*/
template<class Derived>
class fsm_actor : public event_based_actor
{
......
......@@ -80,7 +80,14 @@ class iterator // : std::iterator<forward_iterator_tag, T>
inline pointer operator->() { return m_ptr; }
inline const_pointer operator->() const { return m_ptr; }
/**
* @brief Returns the element this iterator points to.
*/
inline pointer ptr() { return m_ptr; }
/**
* @brief Returns the element this iterator points to.
*/
inline const_pointer ptr() const { return m_ptr; }
private:
......
......@@ -117,9 +117,6 @@ class single_reader_queue
}
}
/**
* @reentrant
*/
void push_back(pointer new_element)
{
pointer e = m_stack.load();
......@@ -155,6 +152,9 @@ class single_reader_queue
return m_cache.empty() && m_stack.load() == nullptr;
}
/**
* @warning call only from the reader (owner)
*/
inline bool not_empty() const
{
return !empty();
......
......@@ -39,7 +39,10 @@
namespace cppa { namespace intrusive {
// like std::forward_list but intrusive and supports push_back()
/**
* @brief A singly linked list similar to std::forward_list
* but intrusive and with push_back() support.
*/
template<class T>
class singly_linked_list
{
......@@ -80,6 +83,9 @@ class singly_linked_list
return *this;
}
/**
* @brief Creates a list from given [first, last] range.
*/
static singly_linked_list from(std::pair<pointer, pointer> const& p)
{
singly_linked_list result;
......@@ -102,7 +108,7 @@ class singly_linked_list
inline iterator before_begin() { return &m_head; }
inline const_iterator before_begin() const { return &m_head; }
inline const_iterator before_cbegin() const { return &m_head; }
inline const_iterator cbefore_begin() const { return &m_head; }
inline iterator begin() { return m_head.next; }
inline const_iterator begin() const { return m_head.next; }
......@@ -118,13 +124,23 @@ class singly_linked_list
// capacity
/**
* @brief Returns true if <tt>{@link begin()} == {@link end()}</tt>.
*/
inline bool empty() const { return m_head.next == nullptr; }
/**
* @brief Returns true if <tt>{@link begin()} != {@link end()}</tt>.
*/
inline bool not_empty() const { return m_head.next != nullptr; }
// no size member function because it would have O(n) complexity
// modifiers
/**
* @brief Deletes all elements.
* @post {@link empty()}
*/
void clear()
{
if (not_empty())
......@@ -141,20 +157,32 @@ class singly_linked_list
}
}
iterator insert_after(iterator i, pointer what)
/**
* @brief Inserts @p what after @p i.
* @returns An iterator to the inserted element.
*/
iterator insert_after(iterator pos, pointer what)
{
what->next = i->next;
i->next = what;
if (i == m_tail) m_tail = what;
what->next = pos->next;
pos->next = what;
if (pos == m_tail) m_tail = what;
return what;
}
/**
* @brief Constructs an element from @p args in-place after @p pos.
* @returns An iterator to the inserted element.
*/
template<typename... Args>
void emplace_after(iterator i, Args&&... args)
void emplace_after(iterator pos, Args&&... args)
{
insert_after(i, new value_type(std::forward<Args>(args)...));
insert_after(pos, new value_type(std::forward<Args>(args)...));
}
/**
* @brief Deletes the element after @p pos.
* @returns An iterator to the element following the erased one.
*/
iterator erase_after(iterator pos)
{
CPPA_REQUIRE(pos != nullptr);
......@@ -168,7 +196,9 @@ class singly_linked_list
return pos->next;
}
// removes the element after pos from the list and returns it
/**
* @brief Removes the element after @p pos from the list and returns it.
*/
pointer take_after(iterator pos)
{
CPPA_REQUIRE(pos != nullptr);
......@@ -181,6 +211,9 @@ class singly_linked_list
return next;
}
/**
* @brief Appends @p what to the list.
*/
void push_back(pointer what)
{
what->next = nullptr;
......@@ -188,12 +221,19 @@ class singly_linked_list
m_tail = what;
}
/**
* @brief Creates an element from @p args in-place and appends it
* to the list.
*/
template<typename... Args>
void emplace_back(Args&&... args)
{
push_back(new value_type(std::forward<Args>(args)...));
}
/**
* @brief Inserts @p what as the first element of the list.
*/
void push_front(pointer what)
{
if (empty())
......@@ -207,12 +247,19 @@ class singly_linked_list
}
}
/**
* @brief Creates an element from @p args and inserts it
* as the first element of the list.
*/
template<typename... Args>
void emplace_front(Args&&... args)
{
push_front(new value_type(std::forward<Args>(args)...));
}
/**
* @brief Deletes the first element of the list.
*/
void pop_front()
{
auto x = m_head.next;
......@@ -235,6 +282,10 @@ class singly_linked_list
// pop_back would have complexity O(n)
/**
* @brief Returns the content of the list as [first, last] sequence.
* @post {@link empty()}
*/
std::pair<pointer, pointer> take()
{
if (empty())
......@@ -250,6 +301,12 @@ class singly_linked_list
}
}
/**
* @brief Moves all elements from @p other to @p *this.
* The elements are inserted after @p pos.
* @pre <tt>@p pos != {@link end()}</tt>
* @pre <tt>this != &other</tt>
*/
void splice_after(iterator pos, singly_linked_list&& other)
{
CPPA_REQUIRE(pos != nullptr);
......@@ -268,6 +325,9 @@ class singly_linked_list
}
}
/**
* @brief Removes all elements for which predicate @p returns @p true.
*/
template<typename UnaryPredicate>
void remove_if(UnaryPredicate p)
{
......@@ -276,7 +336,7 @@ class singly_linked_list
{
if (p(*(i->next)))
{
erase_after(i);
(void) erase_after(i);
}
else
{
......@@ -285,6 +345,9 @@ class singly_linked_list
}
}
/**
* @brief Removes all elements that are equal to @p value.
*/
void remove(value_type const& value)
{
remove_if([&](value_type const& other) { return value == other; });
......
......@@ -176,6 +176,65 @@ class on_the_fly_rvalue_builder
namespace cppa {
#ifdef CPPA_DOCUMENTATION
/**
* @brief A wildcard that matches the argument types
* of a given callback. Must be the last argument to {@link on()}.
* @see {@link math_actor_example.cpp Math Actor Example}
*/
constexpr ___ arg_match;
/**
* @brief Left-hand side of a partial function expression.
*
* Equal to <tt>on(arg_match)</tt>.
*/
constexpr ___ on_arg_match;
/**
* @brief A wildcard that matches any value of type @p T.
* @see {@link math_actor_example.cpp Math Actor Example}
*/
template<typename T>
___ val();
/**
* @brief A wildcard that matches any number of any values.
*/
constexpr anything any_vals;
/**
* @brief Left-hand side of a partial function expression that matches values.
*
* This overload can be used with the wildcards {@link cppa::val val},
* {@link cppa::any_vals any_vals} and {@link cppa::arg_match arg_match}.
*/
template<typename Arg0, typename... Args>
___ on(Arg0 const& arg0, Args const&... args);
/**
* @brief Left-hand side of a partial function expression that matches types.
*
* This overload matches types only. The type {@link cppa::anything anything}
* can be used as wildcard to match any number of elements of any types.
*/
template<typename... Ts>
___ on();
/**
* @brief Left-hand side of a partial function expression that matches types.
*
* This overload matches up to four leading atoms.
* The type {@link cppa::anything anything}
* can be used as wildcard to match any number of elements of any types.
*/
template<atom_value... Atoms, typename... Ts>
___ on();
#else
template<typename T>
constexpr typename detail::boxed<T>::type val()
{
......@@ -204,30 +263,29 @@ detail::rvalue_builder<TypeList...> on()
return { };
}
template<atom_value A0, typename... TypeList>
detail::rvalue_builder<atom_value, TypeList...> on()
template<atom_value A0, typename... Ts>
detail::rvalue_builder<atom_value, Ts...> on()
{
return { A0 };
}
template<atom_value A0, atom_value A1, typename... TypeList>
detail::rvalue_builder<atom_value, atom_value, TypeList...> on()
template<atom_value A0, atom_value A1, typename... Ts>
detail::rvalue_builder<atom_value, atom_value, Ts...> on()
{
return { A0, A1 };
}
template<atom_value A0, atom_value A1, atom_value A2, typename... TypeList>
detail::rvalue_builder<atom_value, atom_value,
atom_value, TypeList...> on()
template<atom_value A0, atom_value A1, atom_value A2, typename... Ts>
detail::rvalue_builder<atom_value, atom_value, atom_value, Ts...> on()
{
return { A0, A1, A2 };
}
template<atom_value A0, atom_value A1,
atom_value A2, atom_value A3,
typename... TypeList>
typename... Ts>
detail::rvalue_builder<atom_value, atom_value, atom_value,
atom_value, TypeList...> on()
atom_value, Ts...> on()
{
return { A0, A1, A2, A3 };
}
......@@ -244,6 +302,8 @@ inline detail::rvalue_builder<anything> others()
return { };
}
#endif
} // namespace cppa
#endif // ON_HPP
......@@ -43,6 +43,10 @@ namespace cppa {
class behavior;
/**
* @brief A partial function implementation
* for {@link cppa::any_tuple any_tuples}.
*/
class partial_function
{
......
......@@ -33,6 +33,10 @@
namespace cppa { namespace util {
/**
* @ingroup TypeList
* @brief Predefines the first template parameter of @p Tp1.
*/
template<template<typename, typename> class Tpl, typename Arg1>
struct tbind
{
......
......@@ -47,6 +47,15 @@ uniform_type_info const* uniform_typeid(std::type_info const&);
namespace cppa { namespace util {
/**
* @defgroup TypeList Type list meta-programming utility.
*/
/**
* @addtogroup TypeList
* @{
*/
template<typename... Types> struct type_list;
template<>
......@@ -58,6 +67,9 @@ struct type_list<>
static const size_t size = 0;
};
/**
* @brief A list of types.
*/
template<typename Head, typename... Tail>
struct type_list<Head, Tail...>
{
......@@ -77,6 +89,9 @@ struct type_list<Head, Tail...>
// static list list::zip(list, list)
template<class ListA, class ListB>
struct tl_zip;
/**
* @brief Zips two lists of equal size.
*
......@@ -84,16 +99,14 @@ struct type_list<Head, Tail...>
* e.g., tl_zip<type_list<int,double>,type_list<float,string>>::type
* is type_list<type_pair<int,float>,type_pair<double,string>>.
*/
template<class ListA, class ListB>
struct tl_zip;
template<typename... LhsElements, typename... RhsElements>
struct tl_zip<type_list<LhsElements...>, type_list<RhsElements...> >
{
typedef type_list<type_pair<LhsElements, RhsElements>...> type;
private:
static_assert(type_list<LhsElements...>::size ==
type_list<RhsElements...>::size,
"Lists have different size");
typedef type_list<type_pair<LhsElements, RhsElements>...> type;
};
// list list::reverse()
......@@ -129,27 +142,38 @@ struct tl_reverse
* index @p Pos.
*/
template<class List, typename What, int Pos = 0>
struct tl_find;
struct tl_find_impl;
template<typename What, int Pos>
struct tl_find<type_list<>, What, Pos>
struct tl_find_impl<type_list<>, What, Pos>
{
static constexpr int value = -1;
typedef type_list<> rest_list;
};
template<typename What, int Pos, typename... Tail>
struct tl_find<type_list<What, Tail...>, What, Pos>
struct tl_find_impl<type_list<What, Tail...>, What, Pos>
{
static constexpr int value = Pos;
typedef type_list<Tail...> rest_list;
};
template<typename What, int Pos, typename Head, typename... Tail>
struct tl_find<type_list<Head, Tail...>, What, Pos>
struct tl_find_impl<type_list<Head, Tail...>, What, Pos>
{
static constexpr int value = tl_find<type_list<Tail...>, What, Pos+1>::value;
typedef typename tl_find<type_list<Tail...>, What, Pos+1>::rest_list rest_list;
static constexpr int value = tl_find_impl<type_list<Tail...>, What, Pos+1>::value;
typedef typename tl_find_impl<type_list<Tail...>, What, Pos+1>::rest_list rest_list;
};
/**
* @brief Finds the first element of type @p What beginning at
* index @p Pos.
*/
template<class List, class What, int Pos = 0>
struct tl_find
{
static constexpr int value = tl_find_impl<List, What, Pos>::value;
typedef typename tl_find_impl<List, What, Pos>::rest_list rest_list;
};
// list list::first_n(size_t)
......@@ -175,9 +199,10 @@ struct tl_first_n_impl<N, type_list<L0, L...>, T...>
template<class List, size_t N>
struct tl_first_n
{
typedef typename tl_first_n_impl<N, List>::type type;
private:
static_assert(N > 0, "N == 0");
static_assert(List::size >= N, "List::size < N");
typedef typename tl_first_n_impl<N, List>::type type;
};
// bool list::forall(predicate)
......@@ -277,12 +302,12 @@ struct tl_zipped_forall<type_list<>, Predicate>
// static list list::concat(list, list)
/**
* @brief Concatenates two lists.
*/
template<typename ListA, typename ListB>
struct tl_concat;
/**
* @brief Concatenates two lists.
*/
template<typename... ListATypes, typename... ListBTypes>
struct tl_concat<type_list<ListATypes...>, type_list<ListBTypes...> >
{
......@@ -291,12 +316,12 @@ struct tl_concat<type_list<ListATypes...>, type_list<ListBTypes...> >
// list list::appy(trait)
/**
* @brief Applies a "template function" to each element in the list.
*/
template<typename List, template<typename> class Trait>
struct tl_apply;
/**
* @brief Applies a "template function" to each element in the list.
*/
template<template<typename> class Trait, typename... Elements>
struct tl_apply<type_list<Elements...>, Trait>
{
......@@ -305,13 +330,13 @@ struct tl_apply<type_list<Elements...>, Trait>
// list list::zipped_apply(trait)
/**
* @brief Applies a binary "template function" to each element
* in the zipped list.
*/
template<typename List, template<typename, typename> class Trait>
struct tl_zipped_apply;
/**
* @brief Applies a "binary template function" to each element
* in the zipped list.
*/
template<template<typename, typename> class Trait, typename... T>
struct tl_zipped_apply<type_list<T...>, Trait>
{
......@@ -349,12 +374,12 @@ struct tl_at_impl<0, E0, E...>
typedef E0 type;
};
/**
* @brief Gets element at index @p N of @p List.
*/
template<class List, size_t N>
struct tl_at;
/**
* @brief Gets element at index @p N of @p List.
*/
template<size_t N, typename... E>
struct tl_at<type_list<E...>, N>
{
......@@ -364,12 +389,12 @@ struct tl_at<type_list<E...>, N>
// list list::prepend(type)
/**
* @brief Creates a new list with @p What prepended to @p List.
*/
template<class List, typename What>
struct tl_prepend;
/**
* @brief Creates a new list with @p What prepended to @p List.
*/
template<typename What, typename... T>
struct tl_prepend<type_list<T...>, What>
{
......@@ -401,12 +426,12 @@ struct tl_filter_impl<type_list<T0, T...>, true, S...>
typedef typename tl_prepend<typename tl_filter_impl<type_list<T...>, S...>::type, T0>::type type;
};
/**
* @brief Create a new list containing all elements which satisfy @p Predicate.
*/
template<class List, template<typename> class Predicate>
struct tl_filter;
/**
* @brief Create a new list containing all elements which satisfy @p Predicate.
*/
template<template<typename> class Predicate, typename... T>
struct tl_filter<type_list<T...>, Predicate>
{
......@@ -426,6 +451,9 @@ struct tl_filter_not<type_list<T...>, Predicate>
typedef typename tl_filter_impl<type_list<T...>, !Predicate<T>::value...>::type type;
};
/**
* @}
*/
} } // namespace cppa::util
#endif // LIBCPPA_UTIL_TYPE_LIST_HPP
......@@ -33,6 +33,10 @@
namespace cppa { namespace util {
/**
* @ingroup TypeList
* @brief A pair of two types.
*/
template<typename First, typename Second>
struct type_pair
{
......
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \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/>. *
\******************************************************************************/
#include <vector>
#include <chrono>
#include <sstream>
......
......@@ -8,13 +8,15 @@ using namespace cppa;
void math_actor()
{
// receive messages in an endless loop
receive_loop
(
on<atom("plus"), int, int>() >> [](int a, int b)
// "arg_match" matches the parameter types of given lambda expression
on(atom("plus"), arg_match) >> [](int a, int b)
{
reply(atom("result"), a + b);
},
on<atom("minus"), int, int>() >> [](int a, int b)
on(atom("minus"), arg_match) >> [](int a, int b)
{
reply(atom("result"), a - b);
}
......@@ -28,6 +30,7 @@ int main()
send(ma, atom("plus"), 1, 2);
receive
(
// on<> matches types only, but allows up to four leading atoms
on<atom("result"), int>() >> [](int result)
{
cout << "1 + 2 = " << result << endl;
......@@ -36,7 +39,8 @@ int main()
send(ma, atom("minus"), 1, 2);
receive
(
on<atom("result"), int>() >> [](int result)
// on() matches values; use val<T> to match any value of type T
on(atom("result"), val<int>) >> [](int result)
{
cout << "1 - 2 = " << result << endl;
}
......
......@@ -74,7 +74,7 @@ BRIEF_MEMBER_DESC = YES
# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
# brief descriptions will be completely suppressed.
REPEAT_BRIEF = NO
REPEAT_BRIEF = YES
# This tag implements a quasi-intelligent brief description abbreviator
# that is used to form the text in various listings. Each string
......@@ -92,7 +92,7 @@ ABBREVIATE_BRIEF =
# Doxygen will generate a detailed section even if there is only a brief
# description.
ALWAYS_DETAILED_SEC = YES
ALWAYS_DETAILED_SEC = NO
# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
# inherited members of a class in the documentation of that class as if those
......@@ -337,7 +337,7 @@ EXTRACT_ANON_NSPACES = NO
# various overviews, but no documentation section is generated.
# This option has no effect if EXTRACT_ALL is enabled.
HIDE_UNDOC_MEMBERS = YES
HIDE_UNDOC_MEMBERS = NO
# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
# undocumented classes that are normally visible in the class hierarchy.
......@@ -565,7 +565,7 @@ WARN_LOGFILE =
# directories like "/usr/src/myproject". Separate the files or directories
# with spaces.
INPUT = cppa/ cppa/util cppa/detail
INPUT = cppa/ cppa/util cppa/intrusive
# This tag can be used to specify the character encoding of the source files
# that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is
......@@ -1508,4 +1508,4 @@ DOT_CLEANUP = YES
# The SEARCHENGINE tag specifies whether or not a search engine should be
# used. If set to NO the values of all tags below this one will be ignored.
SEARCHENGINE = NO
SEARCHENGINE = YES
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