Commit c63d96b4 authored by Dominik Charousset's avatar Dominik Charousset

fixed lots of warnings, removed lockfree::queue

this patch fixes lots of warnings about unsafe float comparison,
signess-errors, implicit conversions and handling of enums in
switch statements; furthermore, this patch removes
`boost::lockfree::queue`, mainly because it can hold a maximum
of 2^16 values (which is not accounted for in the implementation
of the scheduler)
parent 278cc01c
...@@ -29,35 +29,6 @@ if ("${CMAKE_GENERATOR}" STREQUAL "Xcode") ...@@ -29,35 +29,6 @@ if ("${CMAKE_GENERATOR}" STREQUAL "Xcode")
set(LIBRARY_OUTPUT_PATH "${EXECUTABLE_OUTPUT_PATH}") set(LIBRARY_OUTPUT_PATH "${EXECUTABLE_OUTPUT_PATH}")
endif () endif ()
# check if the user provided CXXFLAGS on the command line
if (CMAKE_CXX_FLAGS)
set(CXXFLAGS_PROVIDED true)
set(CMAKE_CXX_FLAGS_DEBUG "")
set(CMAKE_CXX_FLAGS_MINSIZEREL "")
set(CMAKE_CXX_FLAGS_RELEASE "")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "")
else (CMAKE_CXX_FLAGS)
set(CXXFLAGS_PROVIDED false)
set(CMAKE_CXX_FLAGS "-std=c++11 -Wextra -Wall -pedantic")
if (MINGW)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DWIN32")
include (GenerateExportHeader)
endif(MINGW)
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os")
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g")
endif (CMAKE_CXX_FLAGS)
include(CheckIncludeFileCXX)
check_include_file_cxx("valgrind/valgrind.h" HAVE_VALGRIND_H)
if (HAVE_VALGRIND_H)
set(VALGRIND "yes")
add_definitions(-DCPPA_ANNOTATE_VALGRIND)
else (HAVE_VALGRIND_H)
set(VALGRIND "no")
endif (HAVE_VALGRIND_H)
# check for g++ >= 4.7 or clang++ > = 3.2 # check for g++ >= 4.7 or clang++ > = 3.2
try_run(ProgramResult try_run(ProgramResult
CompilationSucceeded CompilationSucceeded
...@@ -88,6 +59,39 @@ else () ...@@ -88,6 +59,39 @@ else ()
"or is not supported") "or is not supported")
endif () endif ()
# check if the user provided CXXFLAGS on the command line
if (CMAKE_CXX_FLAGS)
set(CXXFLAGS_PROVIDED true)
set(CMAKE_CXX_FLAGS_DEBUG "")
set(CMAKE_CXX_FLAGS_MINSIZEREL "")
set(CMAKE_CXX_FLAGS_RELEASE "")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "")
else (CMAKE_CXX_FLAGS)
set(CXXFLAGS_PROVIDED false)
if (MORE_CLANG_WARNINGS AND "${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
set(CMAKE_CXX_FLAGS "-std=c++11 -pedantic -Weverything -Wno-c++98-compat -Wno-padded -Wno-documentation-unknown-command -Wno-exit-time-destructors -Wno-global-constructors -Wno-missing-prototypes -Wno-c++98-compat-pedantic -Wno-unused-member-function -Wno-unused-const-variable")
else ()
set(CMAKE_CXX_FLAGS "-std=c++11 -Wextra -Wall -pedantic")
endif ()
if (MINGW)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DWIN32")
include (GenerateExportHeader)
endif(MINGW)
set(CMAKE_CXX_FLAGS_DEBUG "-O0 -g")
set(CMAKE_CXX_FLAGS_MINSIZEREL "-Os")
set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -g")
endif (CMAKE_CXX_FLAGS)
include(CheckIncludeFileCXX)
check_include_file_cxx("valgrind/valgrind.h" HAVE_VALGRIND_H)
if (HAVE_VALGRIND_H)
set(VALGRIND "yes")
add_definitions(-DCPPA_ANNOTATE_VALGRIND)
else (HAVE_VALGRIND_H)
set(VALGRIND "no")
endif (HAVE_VALGRIND_H)
# set build type (evaluate ENABLE_DEBUG flag) # set build type (evaluate ENABLE_DEBUG flag)
if (ENABLE_DEBUG) if (ENABLE_DEBUG)
set(CMAKE_BUILD_TYPE Debug) set(CMAKE_BUILD_TYPE Debug)
...@@ -163,6 +167,7 @@ set(LIBCPPA_SRC ...@@ -163,6 +167,7 @@ set(LIBCPPA_SRC
src/continue_helper.cpp src/continue_helper.cpp
src/cs_thread.cpp src/cs_thread.cpp
src/decorated_tuple.cpp src/decorated_tuple.cpp
src/default_message_queue.cpp
src/actor_proxy.cpp src/actor_proxy.cpp
src/peer.cpp src/peer.cpp
src/peer_acceptor.cpp src/peer_acceptor.cpp
......
...@@ -38,6 +38,7 @@ Usage: $0 [OPTION]... [VAR=VALUE]... ...@@ -38,6 +38,7 @@ Usage: $0 [OPTION]... [VAR=VALUE]...
--with-opencl build libcppa with OpenCL support --with-opencl build libcppa with OpenCL support
--without-memory-management build libcppa without memory management --without-memory-management build libcppa without memory management
--standalone-build build libcppa without Boost or other dependencies --standalone-build build libcppa without Boost or other dependencies
--more-clang-warnings enables most of Clang's warning flags
Installation Directories: Installation Directories:
--prefix=PREFIX installation directory [/usr/local] --prefix=PREFIX installation directory [/usr/local]
...@@ -191,6 +192,9 @@ while [ $# -ne 0 ]; do ...@@ -191,6 +192,9 @@ while [ $# -ne 0 ]; do
--standalone-build) --standalone-build)
append_cache_entry STANDALONE_BUILD BOOL true append_cache_entry STANDALONE_BUILD BOOL true
;; ;;
--more-clang-warnings)
append_cache_entry MORE_CLANG_WARNINGS BOOL true
;;
--with-cppa-log-level=*) --with-cppa-log-level=*)
level=$(echo "$optarg" | tr '[:lower:]' '[:upper:]') level=$(echo "$optarg" | tr '[:lower:]' '[:upper:]')
case $level in case $level in
......
...@@ -269,6 +269,7 @@ src/continuable.cpp ...@@ -269,6 +269,7 @@ src/continuable.cpp
src/continue_helper.cpp src/continue_helper.cpp
src/cs_thread.cpp src/cs_thread.cpp
src/decorated_tuple.cpp src/decorated_tuple.cpp
src/default_message_queue.cpp
src/demangle.cpp src/demangle.cpp
src/deserializer.cpp src/deserializer.cpp
src/duration.cpp src/duration.cpp
......
...@@ -68,6 +68,7 @@ ...@@ -68,6 +68,7 @@
# define CPPA_PUSH_WARNINGS \ # define CPPA_PUSH_WARNINGS \
_Pragma("clang diagnostic push") \ _Pragma("clang diagnostic push") \
_Pragma("clang diagnostic ignored \"-Wall\"") \ _Pragma("clang diagnostic ignored \"-Wall\"") \
_Pragma("clang diagnostic ignored \"-Wextra\"") \
_Pragma("clang diagnostic ignored \"-Werror\"") \ _Pragma("clang diagnostic ignored \"-Werror\"") \
_Pragma("clang diagnostic ignored \"-Wdeprecated\"") \ _Pragma("clang diagnostic ignored \"-Wdeprecated\"") \
_Pragma("clang diagnostic ignored \"-Wdisabled-macro-expansion\"") \ _Pragma("clang diagnostic ignored \"-Wdisabled-macro-expansion\"") \
...@@ -75,6 +76,10 @@ ...@@ -75,6 +76,10 @@
_Pragma("clang diagnostic ignored \"-Wdocumentation\"") \ _Pragma("clang diagnostic ignored \"-Wdocumentation\"") \
_Pragma("clang diagnostic ignored \"-Wweak-vtables\"") \ _Pragma("clang diagnostic ignored \"-Wweak-vtables\"") \
_Pragma("clang diagnostic ignored \"-Wunused-parameter\"") \ _Pragma("clang diagnostic ignored \"-Wunused-parameter\"") \
_Pragma("clang diagnostic ignored \"-Wswitch-enum\"") \
_Pragma("clang diagnostic ignored \"-Wshadow\"") \
_Pragma("clang diagnostic ignored \"-Wconversion\"") \
_Pragma("clang diagnostic ignored \"-Wcast-align\"") \
_Pragma("clang diagnostic ignored \"-Wundef\"") _Pragma("clang diagnostic ignored \"-Wundef\"")
# define CPPA_POP_WARNINGS \ # define CPPA_POP_WARNINGS \
_Pragma("clang diagnostic pop") _Pragma("clang diagnostic pop")
...@@ -138,8 +143,8 @@ using ::backtrace_symbols_fd; ...@@ -138,8 +143,8 @@ using ::backtrace_symbols_fd;
printf("%s:%u: requirement failed '%s'\n", file, line, stmt); \ printf("%s:%u: requirement failed '%s'\n", file, line, stmt); \
{ \ { \
void* array[10]; \ void* array[10]; \
size_t size = ::cppa::detail::backtrace(array, 10); \ auto cppa_bt_size = ::cppa::detail::backtrace(array, 10); \
::cppa::detail::backtrace_symbols_fd(array, size, 2); \ ::cppa::detail::backtrace_symbols_fd(array, cppa_bt_size, 2); \
} \ } \
abort() abort()
# define CPPA_REQUIRE(stmt) \ # define CPPA_REQUIRE(stmt) \
......
...@@ -44,6 +44,8 @@ class container_tuple_view : public abstract_tuple { ...@@ -44,6 +44,8 @@ class container_tuple_view : public abstract_tuple {
typedef abstract_tuple super; typedef abstract_tuple super;
typedef typename Container::difference_type difference_type;
public: public:
typedef typename Container::value_type value_type; typedef typename Container::value_type value_type;
...@@ -54,33 +56,35 @@ class container_tuple_view : public abstract_tuple { ...@@ -54,33 +56,35 @@ class container_tuple_view : public abstract_tuple {
if (!take_ownership) m_ptr.get_deleter().disable(); if (!take_ownership) m_ptr.get_deleter().disable();
} }
size_t size() const { size_t size() const override {
return m_ptr->size(); return m_ptr->size();
} }
abstract_tuple* copy() const { abstract_tuple* copy() const override {
return new container_tuple_view{new Container(*m_ptr), true}; return new container_tuple_view{new Container(*m_ptr), true};
} }
const void* at(size_t pos) const { const void* at(size_t pos) const override {
CPPA_REQUIRE(pos < size()); CPPA_REQUIRE(pos < size());
CPPA_REQUIRE(static_cast<difference_type>(pos) >= 0);
auto i = m_ptr->cbegin(); auto i = m_ptr->cbegin();
std::advance(i, pos); std::advance(i, static_cast<difference_type>(pos));
return &(*i); return &(*i);
} }
void* mutable_at(size_t pos) { void* mutable_at(size_t pos) override {
CPPA_REQUIRE(pos < size()); CPPA_REQUIRE(pos < size());
CPPA_REQUIRE(static_cast<difference_type>(pos) >= 0);
auto i = m_ptr->begin(); auto i = m_ptr->begin();
std::advance(i, pos); std::advance(i, static_cast<difference_type>(pos));
return &(*i); return &(*i);
} }
const uniform_type_info* type_at(size_t) const { const uniform_type_info* type_at(size_t) const override {
return static_types_array<value_type>::arr[0]; return static_types_array<value_type>::arr[0];
} }
const std::string* tuple_type_names() const { const std::string* tuple_type_names() const override {
static std::string result = demangle<value_type>(); static std::string result = demangle<value_type>();
return &result; return &result;
} }
......
...@@ -34,6 +34,8 @@ ...@@ -34,6 +34,8 @@
#include <type_traits> #include <type_traits>
#include "cppa/unit.hpp" #include "cppa/unit.hpp"
#include "cppa/util/algorithm.hpp"
#include "cppa/util/type_list.hpp" #include "cppa/util/type_list.hpp"
#include "cppa/util/type_traits.hpp" #include "cppa/util/type_traits.hpp"
...@@ -60,7 +62,7 @@ template<typename T> ...@@ -60,7 +62,7 @@ template<typename T>
struct vg_cmp { struct vg_cmp {
template<typename U> template<typename U>
inline static bool _(const T& lhs, const U& rhs) { inline static bool _(const T& lhs, const U& rhs) {
return lhs == rhs; return util::safe_equal(lhs, rhs);
} }
}; };
......
...@@ -42,6 +42,7 @@ ...@@ -42,6 +42,7 @@
#include "cppa/optional.hpp" #include "cppa/optional.hpp"
#include "cppa/util/call.hpp" #include "cppa/util/call.hpp"
#include "cppa/util/algorithm.hpp"
#include "cppa/util/type_traits.hpp" #include "cppa/util/type_traits.hpp"
#include "cppa/util/rebindable_reference.hpp" #include "cppa/util/rebindable_reference.hpp"
...@@ -101,13 +102,15 @@ struct guard_expr { ...@@ -101,13 +102,15 @@ struct guard_expr {
}; };
#define CPPA_FORALL_OPS(SubMacro) \ /*
* @brief Invokes SubMacro for "+", "-", "*", "/", "%", "<", "<=", ">" and ">=".
**/
#define CPPA_FORALL_DEFAULT_OPS(SubMacro) \
SubMacro (addition_op, +) SubMacro (subtraction_op, -) \ SubMacro (addition_op, +) SubMacro (subtraction_op, -) \
SubMacro (multiplication_op, *) SubMacro (division_op, /) \ SubMacro (multiplication_op, *) SubMacro (division_op, /) \
SubMacro (modulo_op, %) SubMacro (less_op, <) \ SubMacro (modulo_op, %) SubMacro (less_op, <) \
SubMacro (less_eq_op, <=) SubMacro (greater_op, >) \ SubMacro (less_eq_op, <=) SubMacro (greater_op, >) \
SubMacro (greater_eq_op, >=) SubMacro (equal_op, ==) \ SubMacro (greater_eq_op, >=)
SubMacro (not_equal_op, !=)
/** /**
* @brief Creates a reference wrapper similar to std::reference_wrapper<const T> * @brief Creates a reference wrapper similar to std::reference_wrapper<const T>
...@@ -418,7 +421,9 @@ ge_concatenate(T1 first, T2 second, ...@@ -418,7 +421,9 @@ ge_concatenate(T1 first, T2 second,
return ge_concatenate< EnumValue >(v1, v2); \ return ge_concatenate< EnumValue >(v1, v2); \
} }
CPPA_FORALL_OPS(CPPA_GE_OPERATOR) CPPA_FORALL_DEFAULT_OPS(CPPA_GE_OPERATOR)
CPPA_GE_OPERATOR(equal_op, ==)
CPPA_GE_OPERATOR(not_equal_op, !=)
template<operator_id OP> template<operator_id OP>
struct ge_eval_op; struct ge_eval_op;
...@@ -430,10 +435,25 @@ struct ge_eval_op; ...@@ -430,10 +435,25 @@ struct ge_eval_op;
-> decltype(lhs Operator rhs) { return lhs Operator rhs; } \ -> decltype(lhs Operator rhs) { return lhs Operator rhs; } \
}; };
CPPA_FORALL_OPS(CPPA_EVAL_OP_IMPL) CPPA_FORALL_DEFAULT_OPS(CPPA_EVAL_OP_IMPL)
CPPA_EVAL_OP_IMPL(logical_and_op, &&) CPPA_EVAL_OP_IMPL(logical_and_op, &&)
CPPA_EVAL_OP_IMPL(logical_or_op, ||) CPPA_EVAL_OP_IMPL(logical_or_op, ||)
template<> struct ge_eval_op<equal_op> {
template<typename T1, typename T2>
static inline bool _(const T1& lhs, const T2& rhs) {
return util::safe_equal(lhs, rhs);
}
};
template<> struct ge_eval_op<not_equal_op> {
template<typename T1, typename T2>
static inline bool _(const T1& lhs, const T2& rhs) {
return !util::safe_equal(lhs, rhs);
}
};
template<typename T, class Tuple> template<typename T, class Tuple>
struct ge_result_ { struct ge_result_ {
typedef typename ge_unbound<T, Tuple>::type type; typedef typename ge_unbound<T, Tuple>::type type;
......
...@@ -81,6 +81,8 @@ class blocking_single_reader_queue { ...@@ -81,6 +81,8 @@ class blocking_single_reader_queue {
// actor no longer alive // actor no longer alive
return false; return false;
} }
// should be unreachable
CPPA_CRITICAL("invalid result of enqueue()");
} }
inline void clear() { inline void clear() {
......
...@@ -42,7 +42,7 @@ namespace cppa { namespace intrusive { ...@@ -42,7 +42,7 @@ namespace cppa { namespace intrusive {
enum enqueue_result { enqueued, first_enqueued, queue_closed }; enum enqueue_result { enqueued, first_enqueued, queue_closed };
/** /**
* @brief An intrusive, thread safe queue implementation. * @brief An intrusive, thread-safe queue implementation.
* @note For implementation details see * @note For implementation details see
* http://libcppa.blogspot.com/2011/04/mailbox-part-1.html * http://libcppa.blogspot.com/2011/04/mailbox-part-1.html
*/ */
......
...@@ -31,6 +31,8 @@ ...@@ -31,6 +31,8 @@
#ifndef CPPA_MESSAGE_QUEUE_HPP #ifndef CPPA_MESSAGE_QUEUE_HPP
#define CPPA_MESSAGE_QUEUE_HPP #define CPPA_MESSAGE_QUEUE_HPP
#include <vector>
#include "cppa/any_tuple.hpp" #include "cppa/any_tuple.hpp"
#include "cppa/ref_counted.hpp" #include "cppa/ref_counted.hpp"
#include "cppa/message_header.hpp" #include "cppa/message_header.hpp"
...@@ -45,6 +47,8 @@ class default_message_queue : public ref_counted { ...@@ -45,6 +47,8 @@ class default_message_queue : public ref_counted {
typedef value_type& reference; typedef value_type& reference;
~default_message_queue();
template<typename... Ts> template<typename... Ts>
void emplace(Ts&&... args) { void emplace(Ts&&... args) {
m_impl.emplace_back(std::forward<Ts>(args)...); m_impl.emplace_back(std::forward<Ts>(args)...);
......
...@@ -105,7 +105,16 @@ class context_switching_resume { ...@@ -105,7 +105,16 @@ class context_switching_resume {
// wait until someone re-schedules that actor // wait until someone re-schedules that actor
return resumable::resume_later; return resumable::resume_later;
} }
default: { CPPA_CRITICAL("illegal yield result"); } case actor_state::about_to_block:
CPPA_CRITICAL("attempt to set state from "
"about_to_block to blocked "
"failed: state is still set "
"to about_to_block");
case actor_state::done:
CPPA_CRITICAL("attempt to set state from "
"about_to_block to blocked "
"failed: state is set "
"to done");
} }
break; break;
} }
......
...@@ -371,6 +371,8 @@ class invoke_policy { ...@@ -371,6 +371,8 @@ class invoke_policy {
return hm_cache_msg; return hm_cache_msg;
} }
} }
// should be unreachable
CPPA_CRITICAL("invalid message type");
} }
Derived* dptr() { Derived* dptr() {
......
...@@ -52,8 +52,8 @@ class actor_widget_mixin : public Base { ...@@ -52,8 +52,8 @@ class actor_widget_mixin : public Base {
message_pointer mptr; message_pointer mptr;
event_type(message_pointer mptr) event_type(message_pointer ptr)
: QEvent(static_cast<QEvent::Type>(EventId)), mptr(std::move(mptr)) { } : QEvent(static_cast<QEvent::Type>(EventId)), mptr(std::move(ptr)) { }
}; };
......
...@@ -31,8 +31,10 @@ ...@@ -31,8 +31,10 @@
#ifndef CPPA_UTIL_SPLIT_HPP #ifndef CPPA_UTIL_SPLIT_HPP
#define CPPA_UTIL_SPLIT_HPP #define CPPA_UTIL_SPLIT_HPP
#include <cmath> // fabs
#include <string> #include <string>
#include <vector> #include <vector>
#include <limits>
#include <sstream> #include <sstream>
#include <algorithm> #include <algorithm>
#include <type_traits> #include <type_traits>
...@@ -74,6 +76,31 @@ void splice(std::string& str, const std::string& glue, T&& arg, Ts&&... args) { ...@@ -74,6 +76,31 @@ void splice(std::string& str, const std::string& glue, T&& arg, Ts&&... args) {
splice(str, glue, std::forward<Ts>(args)...); splice(str, glue, std::forward<Ts>(args)...);
} }
/**
* @brief Compares two values by using @p operator== unless two floating
* point numbers are compared. In the latter case, the function
* performs an epsilon comparison.
*/
template<typename T, typename U>
typename std::enable_if<
!std::is_floating_point<T>::value && !std::is_floating_point<U>::value,
bool
>::type
safe_equal(const T& lhs, const U& rhs) {
return lhs == rhs;
}
template<typename T, typename U>
typename std::enable_if<
std::is_floating_point<T>::value || std::is_floating_point<U>::value,
bool
>::type
safe_equal(const T& lhs, const U& rhs) {
typedef decltype(lhs - rhs) res_type;
return std::fabs(lhs - rhs) <= std::numeric_limits<res_type>::epsilon();
}
} } // namespace cppa::util } } // namespace cppa::util
#endif // CPPA_UTIL_SPLIT_HPP #endif // CPPA_UTIL_SPLIT_HPP
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include "cppa/get.hpp" #include "cppa/get.hpp"
#include "cppa/util/algorithm.hpp"
#include "cppa/util/type_list.hpp" #include "cppa/util/type_list.hpp"
#include "cppa/util/type_traits.hpp" #include "cppa/util/type_traits.hpp"
...@@ -47,7 +48,7 @@ do_get(const Tuple<Ts...>& t) { ...@@ -47,7 +48,7 @@ do_get(const Tuple<Ts...>& t) {
template<size_t N, typename LhsTuple, typename RhsTuple> template<size_t N, typename LhsTuple, typename RhsTuple>
struct cmp_helper { struct cmp_helper {
inline static bool cmp(const LhsTuple& lhs, const RhsTuple& rhs) { inline static bool cmp(const LhsTuple& lhs, const RhsTuple& rhs) {
return do_get<N>(lhs) == do_get<N>(rhs) return util::safe_equal(do_get<N>(lhs), do_get<N>(rhs))
&& cmp_helper<N-1, LhsTuple, RhsTuple>::cmp(lhs, rhs); && cmp_helper<N-1, LhsTuple, RhsTuple>::cmp(lhs, rhs);
} }
}; };
......
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
#include <string> #include <string>
#include <chrono> #include <chrono>
#include <cstdint> #include <cstdint>
#include <stdexcept>
namespace cppa { namespace util { namespace cppa { namespace util {
......
...@@ -108,7 +108,9 @@ class limited_vector { ...@@ -108,7 +108,9 @@ class limited_vector {
void assign(InputIterator first, InputIterator last, void assign(InputIterator first, InputIterator last,
// dummy SFINAE argument // dummy SFINAE argument
typename std::iterator_traits<InputIterator>::pointer = 0) { typename std::iterator_traits<InputIterator>::pointer = 0) {
resize(std::distance(first, last)); auto dist = std::distance(first, last);
CPPA_REQUIRE(dist >= 0);
resize(static_cast<size_t>(dist));
std::copy(first, last, begin()); std::copy(first, last, begin());
} }
...@@ -247,7 +249,8 @@ class limited_vector { ...@@ -247,7 +249,8 @@ class limited_vector {
*/ */
template<class InputIterator> template<class InputIterator>
inline void insert(iterator pos, InputIterator first, InputIterator last) { inline void insert(iterator pos, InputIterator first, InputIterator last) {
auto num_elements = std::distance(first, last); CPPA_REQUIRE(first <= last);
auto num_elements = static_cast<size_t>(std::distance(first, last));
if ((size() + num_elements) > MaxSize) { if ((size() + num_elements) > MaxSize) {
throw std::length_error("limited_vector::insert: too much elements"); throw std::length_error("limited_vector::insert: too much elements");
} }
......
...@@ -33,44 +33,6 @@ ...@@ -33,44 +33,6 @@
#include "cppa/config.hpp" #include "cppa/config.hpp"
#ifndef CPPA_STANDALONE_BUILD
CPPA_PUSH_WARNINGS
#include <boost/lockfree/queue.hpp>
CPPA_POP_WARNINGS
namespace cppa {
namespace util {
template<typename T>
class producer_consumer_list {
public:
inline T* try_pop() {
T* res;
return m_queue.pop(res) ? res : nullptr;
}
inline void push_back(T* ptr) {
m_queue.push(ptr);
}
inline bool empty() {
return m_queue.empty();
}
private:
boost::lockfree::queue<T*> m_queue;
};
} // namespace util
} // namespace cppa
#else // fallback implementation in case Boost is not available
#define CPPA_CACHE_LINE_SIZE 64 #define CPPA_CACHE_LINE_SIZE 64
#include <chrono> #include <chrono>
...@@ -239,6 +201,4 @@ class producer_consumer_list { ...@@ -239,6 +201,4 @@ class producer_consumer_list {
} } // namespace cppa::util } } // namespace cppa::util
#endif // CPPA_STANDALONE_BUILD
#endif // CPPA_PRODUCER_CONSUMER_LIST_HPP #endif // CPPA_PRODUCER_CONSUMER_LIST_HPP
...@@ -11,7 +11,7 @@ using namespace cppa; ...@@ -11,7 +11,7 @@ using namespace cppa;
using std::endl; using std::endl;
int main() { int main() {
std::srand(std::time(0)); std::srand(static_cast<unsigned>(std::time(0)));
for (int i = 1; i <= 50; ++i) { for (int i = 1; i <= 50; ++i) {
spawn<blocking_api>([i](blocking_actor* self) { spawn<blocking_api>([i](blocking_actor* self) {
aout(self) << "Hi there! This is actor nr. " aout(self) << "Hi there! This is actor nr. "
......
...@@ -74,9 +74,17 @@ ...@@ -74,9 +74,17 @@
// libcppa // libcppa
#include "cppa/cppa.hpp" #include "cppa/cppa.hpp"
// disable some clang warnings here caused by CURL and srand(time(nullptr))
#ifdef __clang__
# pragma clang diagnostic ignored "-Wshorten-64-to-32"
# pragma clang diagnostic ignored "-Wdisabled-macro-expansion"
#endif // __clang__
using namespace cppa; using namespace cppa;
namespace color { namespace { namespace {
namespace color {
// UNIX terminal color codes // UNIX terminal color codes
constexpr char reset[] = "\033[0m"; constexpr char reset[] = "\033[0m";
...@@ -98,9 +106,7 @@ constexpr char bold_magenta[] = "\033[1m\033[35m"; ...@@ -98,9 +106,7 @@ constexpr char bold_magenta[] = "\033[1m\033[35m";
constexpr char bold_cyan[] = "\033[1m\033[36m"; constexpr char bold_cyan[] = "\033[1m\033[36m";
constexpr char bold_white[] = "\033[1m\033[37m"; constexpr char bold_white[] = "\033[1m\033[37m";
} } // namespace color::<anonymous> } // namespace color
namespace {
// number of HTTP workers // number of HTTP workers
constexpr size_t num_curl_workers = 10; constexpr size_t num_curl_workers = 10;
...@@ -109,8 +115,6 @@ constexpr size_t num_curl_workers = 10; ...@@ -109,8 +115,6 @@ constexpr size_t num_curl_workers = 10;
constexpr int min_req_interval = 10; constexpr int min_req_interval = 10;
constexpr int max_req_interval = 300; constexpr int max_req_interval = 300;
} // namespace <anonymous>
// provides print utility and each base_actor has a parent // provides print utility and each base_actor has a parent
class base_actor : public event_based_actor { class base_actor : public event_based_actor {
...@@ -369,7 +373,9 @@ class curl_master : public base_actor { ...@@ -369,7 +373,9 @@ class curl_master : public base_actor {
}; };
// signal handling for ctrl+c // signal handling for ctrl+c
namespace { std::atomic<bool> shutdown_flag{false}; } std::atomic<bool> shutdown_flag{false};
} // namespace <anonymous>
int main() { int main() {
// random number setup // random number setup
......
...@@ -16,6 +16,8 @@ using std::chrono::seconds; ...@@ -16,6 +16,8 @@ using std::chrono::seconds;
using namespace std; using namespace std;
using namespace cppa; using namespace cppa;
namespace {
// either taken by a philosopher or available // either taken by a philosopher or available
void chopstick(event_based_actor* self) { void chopstick(event_based_actor* self) {
self->become( self->become(
...@@ -186,6 +188,8 @@ void dining_philosophers() { ...@@ -186,6 +188,8 @@ void dining_philosophers() {
} }
} }
} // namespace <anonymous>
int main(int, char**) { int main(int, char**) {
dining_philosophers(); dining_philosophers();
// real philosophers are never done // real philosophers are never done
......
...@@ -10,6 +10,8 @@ ...@@ -10,6 +10,8 @@
using std::endl; using std::endl;
using namespace cppa; using namespace cppa;
namespace {
struct shutdown_request { }; struct shutdown_request { };
struct plus_request { int a; int b; }; struct plus_request { int a; int b; };
struct minus_request { int a; int b; }; struct minus_request { int a; int b; };
...@@ -77,6 +79,8 @@ void tester(event_based_actor* self, const calculator_type& testee) { ...@@ -77,6 +79,8 @@ void tester(event_based_actor* self, const calculator_type& testee) {
); );
} }
} // namespace <anonymous>
int main() { int main() {
// announce custom message types // announce custom message types
announce<shutdown_request>(); announce<shutdown_request>();
......
...@@ -114,7 +114,6 @@ void ChatWidget::joinGroup() { ...@@ -114,7 +114,6 @@ void ChatWidget::joinGroup() {
} }
string mod = gname.left(pos).toUtf8().constData(); string mod = gname.left(pos).toUtf8().constData();
string gid = gname.midRef(pos+1).toUtf8().constData(); string gid = gname.midRef(pos+1).toUtf8().constData();
group gptr;
try { try {
auto gptr = group::get(mod, gid); auto gptr = group::get(mod, gid);
send_as(as_actor(), as_actor(), atom("join"), gptr); send_as(as_actor(), as_actor(), atom("join"), gptr);
......
...@@ -29,6 +29,9 @@ using namespace std; ...@@ -29,6 +29,9 @@ using namespace std;
using namespace cppa; using namespace cppa;
using namespace cppa::placeholders; using namespace cppa::placeholders;
/*
namespace {
struct line { string str; }; struct line { string str; };
istream& operator>>(istream& is, line& l) { istream& operator>>(istream& is, line& l) {
...@@ -49,6 +52,9 @@ any_tuple split_line(const line& l) { ...@@ -49,6 +52,9 @@ any_tuple split_line(const line& l) {
return s_last_line; return s_last_line;
} }
} // namespace <anonymous>
*/
int main(int argc, char** argv) { int main(int argc, char** argv) {
string name; string name;
...@@ -97,7 +103,8 @@ int main(int argc, char** argv) { ...@@ -97,7 +103,8 @@ int main(int argc, char** argv) {
send_as(client, client, atom("join"), gptr); send_as(client, client, atom("join"), gptr);
} }
mw.show(); mw.show();
return app.exec(); auto res = app.exec();
shutdown(); shutdown();
return 0; await_all_actors_done();
return res;
} }
...@@ -88,10 +88,10 @@ void client_bhvr(event_based_actor* self, const string& host, uint16_t port, con ...@@ -88,10 +88,10 @@ void client_bhvr(event_based_actor* self, const string& host, uint16_t port, con
aout(self) << "*** server down, try to reconnect ..." << endl; aout(self) << "*** server down, try to reconnect ..." << endl;
client_bhvr(self, host, port, invalid_actor); client_bhvr(self, host, port, invalid_actor);
}, },
on(atom("rebind"), arg_match) >> [=](const string& host, uint16_t port) { on(atom("rebind"), arg_match) >> [=](const string& nhost, uint16_t nport) {
aout(self) << "*** rebind to new server: " aout(self) << "*** rebind to new server: "
<< host << ":" << port << endl; << nhost << ":" << nport << endl;
client_bhvr(self, host, port, invalid_actor); client_bhvr(self, nhost, nport, invalid_actor);
}, },
on(atom("reconnect")) >> [=] { on(atom("reconnect")) >> [=] {
client_bhvr(self, host, port, invalid_actor); client_bhvr(self, host, port, invalid_actor);
...@@ -120,18 +120,18 @@ void client_repl(const string& host, uint16_t port) { ...@@ -120,18 +120,18 @@ void client_repl(const string& host, uint16_t port) {
// the STL way of line.starts_with("connect") // the STL way of line.starts_with("connect")
else if (equal(begin(connect), end(connect) - 1, begin(line))) { else if (equal(begin(connect), end(connect) - 1, begin(line))) {
match_split(line, ' ') ( match_split(line, ' ') (
on("connect", arg_match) >> [&](string& host, string& sport) { on("connect", arg_match) >> [&](string& nhost, string& sport) {
try { try {
auto lport = std::stoul(sport); auto lport = std::stoul(sport);
if (lport < std::numeric_limits<uint16_t>::max()) { if (lport < std::numeric_limits<uint16_t>::max()) {
auto port = static_cast<uint16_t>(lport); anon_send(client, atom("rebind"), move(nhost),
anon_send(client, atom("rebind"), move(host), port); static_cast<uint16_t>(lport));
} }
else { else {
cout << lport << " is not a valid port" << endl; cout << lport << " is not a valid port" << endl;
} }
} }
catch (std::exception& e) { catch (std::exception&) {
cout << "\"" << sport << "\" is not an unsigned integer" cout << "\"" << sport << "\" is not an unsigned integer"
<< endl; << endl;
} }
......
...@@ -20,6 +20,8 @@ using std::endl; ...@@ -20,6 +20,8 @@ using std::endl;
using namespace cppa; using namespace cppa;
namespace {
// a node containing an integer and a vector of children // a node containing an integer and a vector of children
struct tree_node { struct tree_node {
std::uint32_t value; std::uint32_t value;
...@@ -164,6 +166,8 @@ void testee(event_based_actor* self, size_t remaining) { ...@@ -164,6 +166,8 @@ void testee(event_based_actor* self, size_t remaining) {
); );
} }
} // namespace <anonymous>
int main() { int main() {
// the tree_type_info is owned by libcppa after this function call // the tree_type_info is owned by libcppa after this function call
announce(typeid(tree), std::unique_ptr<uniform_type_info>{new tree_type_info}); announce(typeid(tree), std::unique_ptr<uniform_type_info>{new tree_type_info});
......
...@@ -70,6 +70,7 @@ const std::string& abstract_group::module_name() const { ...@@ -70,6 +70,7 @@ const std::string& abstract_group::module_name() const {
return get_module()->name(); return get_module()->name();
} }
namespace {
struct group_nameserver : event_based_actor { struct group_nameserver : event_based_actor {
behavior make_behavior() override { behavior make_behavior() override {
return ( return (
...@@ -81,11 +82,8 @@ struct group_nameserver : event_based_actor { ...@@ -81,11 +82,8 @@ struct group_nameserver : event_based_actor {
} }
); );
} }
~group_nameserver();
}; };
} // namespace <anonymous>
// avoid weak-vtables warning by providing dtor out-of-line
group_nameserver::~group_nameserver() { }
void publish_local_groups(std::uint16_t port, const char* addr) { void publish_local_groups(std::uint16_t port, const char* addr) {
auto gn = spawn<group_nameserver, hidden>(); auto gn = spawn<group_nameserver, hidden>();
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
namespace cppa { namespace cppa {
namespace {
class continuation_decorator : public detail::behavior_impl { class continuation_decorator : public detail::behavior_impl {
typedef behavior_impl super; typedef behavior_impl super;
...@@ -43,8 +44,6 @@ class continuation_decorator : public detail::behavior_impl { ...@@ -43,8 +44,6 @@ class continuation_decorator : public detail::behavior_impl {
typedef typename behavior_impl::pointer pointer; typedef typename behavior_impl::pointer pointer;
~continuation_decorator();
continuation_decorator(continuation_fun fun, pointer ptr) continuation_decorator(continuation_fun fun, pointer ptr)
: super(ptr->timeout()), m_fun(fun), m_decorated(std::move(ptr)) { : super(ptr->timeout()), m_fun(fun), m_decorated(std::move(ptr)) {
CPPA_REQUIRE(m_decorated != nullptr); CPPA_REQUIRE(m_decorated != nullptr);
...@@ -81,9 +80,7 @@ class continuation_decorator : public detail::behavior_impl { ...@@ -81,9 +80,7 @@ class continuation_decorator : public detail::behavior_impl {
pointer m_decorated; pointer m_decorated;
}; };
} // namespace <anonymous>
// avoid weak-vtables warning by providing dtor out-of-line
continuation_decorator::~continuation_decorator() { }
behavior::behavior(const partial_function& fun) : m_impl(fun.m_impl) { } behavior::behavior(const partial_function& fun) : m_impl(fun.m_impl) { }
......
...@@ -184,8 +184,6 @@ namespace { ...@@ -184,8 +184,6 @@ namespace {
// base class for cs_thread pimpls // base class for cs_thread pimpls
struct cst_impl { struct cst_impl {
cst_impl() : m_ctx() { }
virtual ~cst_impl(); virtual ~cst_impl();
virtual void run() = 0; virtual void run() = 0;
...@@ -198,14 +196,13 @@ struct cst_impl { ...@@ -198,14 +196,13 @@ struct cst_impl {
}; };
// avoid weak-vtables warning by providing dtor out-of-line
cst_impl::~cst_impl() { } cst_impl::~cst_impl() { }
namespace {
// a cs_thread representing a thread ('converts' the thread to a cs_thread) // a cs_thread representing a thread ('converts' the thread to a cs_thread)
struct converted_cs_thread : cst_impl { struct converted_cs_thread : cst_impl {
~converted_cs_thread();
converted_cs_thread() { converted_cs_thread() {
init_converted_context(m_converted, m_ctx); init_converted_context(m_converted, m_ctx);
} }
...@@ -218,9 +215,6 @@ struct converted_cs_thread : cst_impl { ...@@ -218,9 +215,6 @@ struct converted_cs_thread : cst_impl {
}; };
// avoid weak-vtables warning by providing dtor out-of-line
converted_cs_thread::~converted_cs_thread() { }
// a cs_thread executing a function // a cs_thread executing a function
struct fun_cs_thread : cst_impl { struct fun_cs_thread : cst_impl {
...@@ -228,7 +222,9 @@ struct fun_cs_thread : cst_impl { ...@@ -228,7 +222,9 @@ struct fun_cs_thread : cst_impl {
m_stack_info = new_stack(m_ctx, m_alloc, m_vgm); m_stack_info = new_stack(m_ctx, m_alloc, m_vgm);
} }
~fun_cs_thread(); ~fun_cs_thread() {
del_stack(m_alloc, m_stack_info, m_vgm);
}
void run() override { void run() override {
m_fun(m_arg); m_fun(m_arg);
...@@ -242,10 +238,7 @@ struct fun_cs_thread : cst_impl { ...@@ -242,10 +238,7 @@ struct fun_cs_thread : cst_impl {
}; };
// avoid weak-vtables warning by providing dtor out-of-line } // namespace <anonymous>
fun_cs_thread::~fun_cs_thread() {
del_stack(m_alloc, m_stack_info, m_vgm);
}
void cst_trampoline(intptr_t iptr) { void cst_trampoline(intptr_t iptr) {
auto ptr = (cst_impl*) iptr; auto ptr = (cst_impl*) iptr;
......
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \L\ \/\ \__/\ \ \L\ \ \ \L\ \/\ \L\.\_ *
* /\____\\ \_\ \_,__/\ \____\\ \ ,__/\ \ ,__/\ \__/.\_\ *
* \/____/ \/_/\/___/ \/____/ \ \ \/ \ \ \/ \/__/\/_/ *
* \ \_\ \ \_\ *
* \/_/ \/_/ *
* *
* Copyright (C) 2011-2013 *
* 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 2.1 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 "cppa/io/default_message_queue.hpp"
namespace cppa {
namespace io {
default_message_queue::~default_message_queue() { }
} // namespace io
} // namespace cppa
...@@ -151,7 +151,9 @@ io::stream_ptr ipv4_io_stream::connect_to(const char* host, ...@@ -151,7 +151,9 @@ io::stream_ptr ipv4_io_stream::connect_to(const char* host,
} }
memset(&serv_addr, 0, sizeof(serv_addr)); memset(&serv_addr, 0, sizeof(serv_addr));
serv_addr.sin_family = AF_INET; serv_addr.sin_family = AF_INET;
memmove(&serv_addr.sin_addr.s_addr, server->h_addr, server->h_length); memmove(&serv_addr.sin_addr.s_addr,
server->h_addr,
static_cast<size_t>(server->h_length));
serv_addr.sin_port = htons(port); serv_addr.sin_port = htons(port);
CPPA_LOGF_DEBUG("call connect()"); CPPA_LOGF_DEBUG("call connect()");
if (connect(fd, (const sockaddr*) &serv_addr, sizeof(serv_addr)) != 0) { if (connect(fd, (const sockaddr*) &serv_addr, sizeof(serv_addr)) != 0) {
......
...@@ -430,18 +430,24 @@ void middleman_loop(middleman_impl* impl) { ...@@ -430,18 +430,24 @@ void middleman_loop(middleman_impl* impl) {
handler->poll([&](event_bitmask mask, continuable* io) { handler->poll([&](event_bitmask mask, continuable* io) {
switch (mask) { switch (mask) {
default: CPPA_CRITICAL("invalid event"); default: CPPA_CRITICAL("invalid event");
case event::none: break; case event::none:
// should not happen
CPPA_LOGF_WARNING("polled an event::none event");
break;
case event::both: case event::both:
case event::write: { case event::write:
CPPA_LOGF_DEBUG("handle event::write for " << io); CPPA_LOGF_DEBUG("handle event::write for " << io);
switch (io->continue_writing()) { switch (io->continue_writing()) {
case continue_writing_result::failure: case continue_writing_result::failure:
io->io_failed(event::write); io->io_failed(event::write);
CPPA_ANNOTATE_FALLTHROUGH; impl->stop_writer(io);
CPPA_LOGF_DEBUG("writer removed because "
"of an error");
break;
case continue_writing_result::closed: case continue_writing_result::closed:
impl->stop_writer(io); impl->stop_writer(io);
CPPA_LOGF_DEBUG("writer removed because " CPPA_LOGF_DEBUG("writer removed because "
"of error write_closed or "); "connection has been closed");
break; break;
case continue_writing_result::done: case continue_writing_result::done:
impl->stop_writer(io); impl->stop_writer(io);
...@@ -454,16 +460,19 @@ void middleman_loop(middleman_impl* impl) { ...@@ -454,16 +460,19 @@ void middleman_loop(middleman_impl* impl) {
// else: fall through // else: fall through
CPPA_LOGF_DEBUG("handle event::both; fall through"); CPPA_LOGF_DEBUG("handle event::both; fall through");
CPPA_ANNOTATE_FALLTHROUGH; CPPA_ANNOTATE_FALLTHROUGH;
}
case event::read: { case event::read: {
CPPA_LOGF_DEBUG("handle event::read for " << io); CPPA_LOGF_DEBUG("handle event::read for " << io);
switch (io->continue_reading()) { switch (io->continue_reading()) {
case continue_reading_result::failure: case continue_reading_result::failure:
io->io_failed(event::read); io->io_failed(event::read);
CPPA_ANNOTATE_FALLTHROUGH; impl->stop_reader(io);
CPPA_LOGF_DEBUG("peer removed because a "
"read error has occured");
break;
case continue_reading_result::closed: case continue_reading_result::closed:
impl->stop_reader(io); impl->stop_reader(io);
CPPA_LOGF_DEBUG("remove peer"); CPPA_LOGF_DEBUG("peer removed because "
"connection has been closed");
break; break;
case continue_reading_result::continue_later: case continue_reading_result::continue_later:
// nothing to do // nothing to do
......
...@@ -78,7 +78,7 @@ void host_id_from_string(const std::string& hash, ...@@ -78,7 +78,7 @@ void host_id_from_string(const std::string& hash,
for (size_t i = 0; i < node_id.size(); ++i) { for (size_t i = 0; i < node_id.size(); ++i) {
// read two characters, each representing 4 bytes // read two characters, each representing 4 bytes
auto& val = node_id[i]; auto& val = node_id[i];
val = hex_char_value(*j++) << 4; val = static_cast<uint8_t>(hex_char_value(*j++) << 4);
val |= hex_char_value(*j++); val |= hex_char_value(*j++);
} }
} }
...@@ -93,7 +93,7 @@ bool equal(const std::string& hash, ...@@ -93,7 +93,7 @@ bool equal(const std::string& hash,
for (size_t i = 0; i < node_id.size(); ++i) { for (size_t i = 0; i < node_id.size(); ++i) {
// read two characters, each representing 4 bytes // read two characters, each representing 4 bytes
std::uint8_t val; std::uint8_t val;
val = hex_char_value(*j++) << 4; val = static_cast<uint8_t>(hex_char_value(*j++) << 4);
val |= hex_char_value(*j++); val |= hex_char_value(*j++);
if (val != node_id[i]) { if (val != node_id[i]) {
return false; return false;
......
...@@ -31,6 +31,9 @@ ...@@ -31,6 +31,9 @@
#include <typeinfo> #include <typeinfo>
#include "cppa/primitive_variant.hpp" #include "cppa/primitive_variant.hpp"
#include "cppa/util/algorithm.hpp"
#include "cppa/detail/type_to_ptype.hpp" #include "cppa/detail/type_to_ptype.hpp"
namespace cppa { namespace cppa {
...@@ -77,7 +80,8 @@ struct comparator { ...@@ -77,7 +80,8 @@ struct comparator {
template<primitive_type PT> template<primitive_type PT>
void operator()(util::pt_token<PT>) { void operator()(util::pt_token<PT>) {
if (rhs.ptype() == PT) { if (rhs.ptype() == PT) {
result = (get<PT>(lhs) == get<PT>(rhs)); result = util::safe_equal(get<PT>(lhs), get<PT>(rhs));
//result = (get<PT>(lhs) == get<PT>(rhs));
} }
} }
}; };
......
...@@ -211,6 +211,8 @@ class string_deserializer : public deserializer { ...@@ -211,6 +211,8 @@ class string_deserializer : public deserializer {
typedef deserializer super; typedef deserializer super;
typedef string::iterator::difference_type difference_type;
string m_str; string m_str;
string::iterator m_pos; string::iterator m_pos;
//size_t m_obj_count; //size_t m_obj_count;
...@@ -338,7 +340,8 @@ class string_deserializer : public deserializer { ...@@ -338,7 +340,8 @@ class string_deserializer : public deserializer {
size_t begin_sequence() { size_t begin_sequence() {
integrity_check(); integrity_check();
consume('{'); consume('{');
return count(m_pos, find(m_pos, m_str.end(), '}'), ',') + 1; auto num_vals = count(m_pos, find(m_pos, m_str.end(), '}'), ',') + 1;
return static_cast<size_t>(num_vals);
} }
void end_sequence() { void end_sequence() {
...@@ -415,7 +418,7 @@ class string_deserializer : public deserializer { ...@@ -415,7 +418,7 @@ class string_deserializer : public deserializer {
throw logic_error("malformed string (unterminated value)"); throw logic_error("malformed string (unterminated value)");
} }
string substr(m_pos, substr_end); string substr(m_pos, substr_end);
m_pos += substr.size(); m_pos += static_cast<difference_type>(substr.size());
if (ptype == pt_u8string || ptype == pt_atom) { if (ptype == pt_u8string || ptype == pt_atom) {
char needle = (ptype == pt_u8string) ? '"' : '\''; char needle = (ptype == pt_u8string) ? '"' : '\'';
// skip trailing " // skip trailing "
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include <array> #include <array>
#include <limits>
#include <string> #include <string>
#include <vector> #include <vector>
#include <cstring> #include <cstring>
...@@ -452,7 +453,9 @@ class uti_base : public uniform_type_info { ...@@ -452,7 +453,9 @@ class uti_base : public uniform_type_info {
} }
bool equals(const void* lhs, const void* rhs) const override { bool equals(const void* lhs, const void* rhs) const override {
return deref(lhs) == deref(rhs); //return util::safe_equal(deref(lhs), deref(rhs));
//return deref(lhs) == deref(rhs);
return eq(deref(lhs), deref(rhs));
} }
void* new_instance(const void* ptr) const override { void* new_instance(const void* ptr) const override {
...@@ -477,6 +480,20 @@ class uti_base : public uniform_type_info { ...@@ -477,6 +480,20 @@ class uti_base : public uniform_type_info {
const std::type_info* m_native; const std::type_info* m_native;
private:
template<typename U>
typename std::enable_if<std::is_floating_point<U>::value, bool>::type
eq(const U& lhs, const U& rhs) const {
return util::safe_equal(lhs, rhs);
}
template<typename U>
typename std::enable_if<!std::is_floating_point<U>::value, bool>::type
eq(const U& lhs, const U& rhs) const {
return lhs == rhs;
}
}; };
template<typename T> template<typename T>
...@@ -890,7 +907,7 @@ class utim_impl : public uniform_type_info_map { ...@@ -890,7 +907,7 @@ class utim_impl : public uniform_type_info_map {
// insert after lower bound (vector is always sorted) // insert after lower bound (vector is always sorted)
auto new_pos = std::distance(m_user_types.begin(), i); auto new_pos = std::distance(m_user_types.begin(), i);
m_user_types.insert(i, uti.release()); m_user_types.insert(i, uti.release());
return m_user_types[new_pos]; return m_user_types[static_cast<size_t>(new_pos)];
} }
} }
......
...@@ -52,7 +52,7 @@ vector<string> split(const string& str, char delim, bool keep_empties) { ...@@ -52,7 +52,7 @@ vector<string> split(const string& str, char delim, bool keep_empties) {
return result; return result;
} }
void verbose_terminate() { void verbose_terminate [[noreturn]] () {
try { throw; } try { throw; }
catch (exception& e) { catch (exception& e) {
CPPA_PRINTERR("terminate called after throwing " CPPA_PRINTERR("terminate called after throwing "
......
...@@ -106,7 +106,7 @@ inline void cppa_check_value(const V1& v1, ...@@ -106,7 +106,7 @@ inline void cppa_check_value(const V1& v1,
size_t line, size_t line,
bool expected = true, bool expected = true,
typename enable_integral<false, V1, V2>::type* = 0) { typename enable_integral<false, V1, V2>::type* = 0) {
if ((v1 == v2) == expected) cppa_passed(fname, line); if (cppa::util::safe_equal(v1, v2) == expected) cppa_passed(fname, line);
else cppa_failed(v1, v2, fname, line); else cppa_failed(v1, v2, fname, line);
} }
......
...@@ -12,8 +12,6 @@ namespace { ...@@ -12,8 +12,6 @@ namespace {
int class0_instances = 0; int class0_instances = 0;
int class1_instances = 0; int class1_instances = 0;
}
struct class0 : ref_counted { struct class0 : ref_counted {
class0() { ++class0_instances; } class0() { ++class0_instances; }
...@@ -41,6 +39,8 @@ class0_ptr get_test_ptr() { ...@@ -41,6 +39,8 @@ class0_ptr get_test_ptr() {
return get_test_rc(); return get_test_rc();
} }
} // namespace <anonymous>
int main() { int main() {
// this test dosn't test thread-safety of intrusive_ptr // this test dosn't test thread-safety of intrusive_ptr
// however, it is thread safe since it uses atomic operations only // however, it is thread safe since it uses atomic operations only
......
...@@ -168,7 +168,8 @@ void test_gref() { ...@@ -168,7 +168,8 @@ void test_gref() {
on<anything>() >> [] { return 2; } on<anything>() >> [] { return 2; }
); );
any_tuple expr19_tup = make_cow_tuple("hello guard!"); any_tuple expr19_tup = make_cow_tuple("hello guard!");
CPPA_CHECK_EQUAL(expr19(expr19_tup), 2); auto res19 = expr19(expr19_tup);
CPPA_CHECK(res19.is<int>() && get<int>(res19) == 2);
partial_function expr20 = expr19; partial_function expr20 = expr19;
enable_case1 = false; enable_case1 = false;
CPPA_CHECK(expr20(expr19_tup) == make_any_tuple(1)); CPPA_CHECK(expr20(expr19_tup) == make_any_tuple(1));
...@@ -219,7 +220,7 @@ void test_match_function() { ...@@ -219,7 +220,7 @@ void test_match_function() {
return "C"; return "C";
} }
); );
CPPA_CHECK_EQUAL(res5, "C"); CPPA_CHECK_EQUAL(get<string>(res5), "C");
} }
void test_match_each() { void test_match_each() {
...@@ -341,7 +342,7 @@ void test_pattern_matching() { ...@@ -341,7 +342,7 @@ void test_pattern_matching() {
return f; return f;
} }
); );
CPPA_CHECK(res && res.is<float>() && get<float>(res) == 4.2f); CPPA_CHECK(res && res.is<float>() && util::safe_equal(get<float>(res), 4.2f));
auto res2 = match(make_any_tuple(23, 4.2f)) ( auto res2 = match(make_any_tuple(23, 4.2f)) (
on(42, arg_match) >> [](double d) { on(42, arg_match) >> [](double d) {
return d; return d;
......
...@@ -137,8 +137,6 @@ void spawn5_client(event_based_actor* self) { ...@@ -137,8 +137,6 @@ void spawn5_client(event_based_actor* self) {
); );
} }
} // namespace <anonymous>
template<typename F> template<typename F>
void await_down(event_based_actor* self, actor ptr, F continuation) { void await_down(event_based_actor* self, actor ptr, F continuation) {
self->become ( self->become (
...@@ -324,6 +322,8 @@ class server : public event_based_actor { ...@@ -324,6 +322,8 @@ class server : public event_based_actor {
}; };
} // namespace <anonymous>
int main(int argc, char** argv) { int main(int argc, char** argv) {
announce<actor_vector>(); announce<actor_vector>();
announce_tuple<atom_value, int>(); announce_tuple<atom_value, int>();
......
...@@ -59,37 +59,19 @@ using namespace cppa::util; ...@@ -59,37 +59,19 @@ using namespace cppa::util;
using cppa::detail::type_to_ptype; using cppa::detail::type_to_ptype;
using cppa::detail::ptype_to_type; using cppa::detail::ptype_to_type;
namespace {
struct struct_a { struct struct_a {
int x; int x;
int y; int y;
}; };
bool operator==(const struct_a& lhs, const struct_a& rhs) {
return lhs.x == rhs.x && lhs.y == rhs.y;
}
bool operator!=(const struct_a& lhs, const struct_a& rhs) {
return !(lhs == rhs);
}
struct struct_b { struct struct_b {
struct_a a; struct_a a;
int z; int z;
list<int> ints; list<int> ints;
}; };
string to_string(const struct_b& what) {
return to_string(object::from(what));
}
bool operator==(const struct_b& lhs, const struct_b& rhs) {
return lhs.a == rhs.a && lhs.z == rhs.z && lhs.ints == rhs.ints;
}
bool operator!=(const struct_b& lhs, const struct_b& rhs) {
return !(lhs == rhs);
}
typedef map<string, u16string> strmap; typedef map<string, u16string> strmap;
struct struct_c { struct struct_c {
...@@ -97,14 +79,6 @@ struct struct_c { ...@@ -97,14 +79,6 @@ struct struct_c {
set<int> ints; set<int> ints;
}; };
bool operator==(const struct_c& lhs, const struct_c& rhs) {
return lhs.strings == rhs.strings && lhs.ints == rhs.ints;
}
bool operator!=(const struct_c& lhs, const struct_c& rhs) {
return !(lhs == rhs);
}
struct raw_struct { struct raw_struct {
string str; string str;
}; };
...@@ -113,10 +87,6 @@ bool operator==(const raw_struct& lhs, const raw_struct& rhs) { ...@@ -113,10 +87,6 @@ bool operator==(const raw_struct& lhs, const raw_struct& rhs) {
return lhs.str == rhs.str; return lhs.str == rhs.str;
} }
bool operator!=(const raw_struct& lhs, const raw_struct& rhs) {
return lhs.str != rhs.str;
}
struct raw_struct_type_info : util::abstract_uniform_type_info<raw_struct> { struct raw_struct_type_info : util::abstract_uniform_type_info<raw_struct> {
void serialize(const void* ptr, serializer* sink) const override { void serialize(const void* ptr, serializer* sink) const override {
auto rs = reinterpret_cast<const raw_struct*>(ptr); auto rs = reinterpret_cast<const raw_struct*>(ptr);
...@@ -150,6 +120,8 @@ void test_ieee_754() { ...@@ -150,6 +120,8 @@ void test_ieee_754() {
CPPA_CHECK_EQUAL(f2, u2); CPPA_CHECK_EQUAL(f2, u2);
} }
} // namespace <anonymous>
int main() { int main() {
CPPA_TEST(test_serialization); CPPA_TEST(test_serialization);
......
...@@ -11,6 +11,8 @@ ...@@ -11,6 +11,8 @@
using namespace std; using namespace std;
using namespace cppa; using namespace cppa;
namespace {
class event_testee : public sb_actor<event_testee> { class event_testee : public sb_actor<event_testee> {
friend class sb_actor<event_testee>; friend class sb_actor<event_testee>;
...@@ -58,7 +60,7 @@ class event_testee : public sb_actor<event_testee> { ...@@ -58,7 +60,7 @@ class event_testee : public sb_actor<event_testee> {
actor spawn_event_testee2(actor parent) { actor spawn_event_testee2(actor parent) {
struct impl : event_based_actor { struct impl : event_based_actor {
actor parent; actor parent;
impl(actor parent) : parent(parent) { } impl(actor parent_actor) : parent(parent_actor) { }
behavior wait4timeout(int remaining) { behavior wait4timeout(int remaining) {
CPPA_LOG_TRACE(CPPA_ARG(remaining)); CPPA_LOG_TRACE(CPPA_ARG(remaining));
return { return {
...@@ -328,7 +330,7 @@ struct master : event_based_actor { ...@@ -328,7 +330,7 @@ struct master : event_based_actor {
struct slave : event_based_actor { struct slave : event_based_actor {
slave(actor master) : master{master} { } slave(actor master_actor) : master{master_actor} { }
behavior make_behavior() override { behavior make_behavior() override {
link_to(master); link_to(master);
...@@ -477,7 +479,6 @@ void test_continuation() { ...@@ -477,7 +479,6 @@ void test_continuation() {
} }
void test_simple_reply_response() { void test_simple_reply_response() {
scoped_actor self;
auto s = spawn([](event_based_actor* self) -> behavior { auto s = spawn([](event_based_actor* self) -> behavior {
return ( return (
others() >> [=]() -> any_tuple { others() >> [=]() -> any_tuple {
...@@ -487,6 +488,7 @@ void test_simple_reply_response() { ...@@ -487,6 +488,7 @@ void test_simple_reply_response() {
} }
); );
}); });
scoped_actor self;
self->send(s, atom("hello")); self->send(s, atom("hello"));
self->receive( self->receive(
others() >> [&] { others() >> [&] {
...@@ -630,7 +632,7 @@ void test_spawn() { ...@@ -630,7 +632,7 @@ void test_spawn() {
self->await_all_other_actors_done(); self->await_all_other_actors_done();
CPPA_CHECKPOINT(); CPPA_CHECKPOINT();
auto st = spawn<fixed_stack>(10); auto st = spawn<fixed_stack>(size_t{10});
// push 20 values // push 20 values
for (int i = 0; i < 20; ++i) self->send(st, atom("push"), i); for (int i = 0; i < 20; ++i) self->send(st, atom("push"), i);
// pop 20 times // pop 20 times
...@@ -660,8 +662,8 @@ void test_spawn() { ...@@ -660,8 +662,8 @@ void test_spawn() {
self->await_all_other_actors_done(); self->await_all_other_actors_done();
CPPA_CHECKPOINT(); CPPA_CHECKPOINT();
auto sync_testee1 = spawn<blocking_api>([](blocking_actor* self) { auto sync_testee1 = spawn<blocking_api>([](blocking_actor* s) {
self->receive ( s->receive (
on(atom("get")) >> [] { on(atom("get")) >> [] {
return make_cow_tuple(42, 2); return make_cow_tuple(42, 2);
} }
...@@ -701,12 +703,12 @@ void test_spawn() { ...@@ -701,12 +703,12 @@ void test_spawn() {
CPPA_PRINT("test sync send"); CPPA_PRINT("test sync send");
CPPA_CHECKPOINT(); CPPA_CHECKPOINT();
auto sync_testee = spawn<blocking_api>([](blocking_actor* self) { auto sync_testee = spawn<blocking_api>([](blocking_actor* s) {
self->receive ( s->receive (
on("hi", arg_match) >> [&](actor from) { on("hi", arg_match) >> [&](actor from) {
self->sync_send(from, "whassup?", self).await( s->sync_send(from, "whassup?", s).await(
on_arg_match >> [&](const string& str) -> string { on_arg_match >> [&](const string& str) -> string {
CPPA_CHECK(self->last_sender() != nullptr); CPPA_CHECK(s->last_sender() != nullptr);
CPPA_CHECK_EQUAL(str, "nothing"); CPPA_CHECK_EQUAL(str, "nothing");
return "goodbye!"; return "goodbye!";
}, },
...@@ -750,15 +752,15 @@ void test_spawn() { ...@@ -750,15 +752,15 @@ void test_spawn() {
CPPA_CHECKPOINT(); CPPA_CHECKPOINT();
auto inflater = [](event_based_actor* self, const string& name, actor buddy) { auto inflater = [](event_based_actor* s, const string& name, actor buddy) {
CPPA_LOGF_TRACE(CPPA_ARG(self) << ", " << CPPA_ARG(name) CPPA_LOGF_TRACE(CPPA_ARG(s) << ", " << CPPA_ARG(name)
<< ", " << CPPA_TARG(buddy, to_string)); << ", " << CPPA_TARG(buddy, to_string));
self->become( s->become(
on_arg_match >> [=](int n, const string& s) { on_arg_match >> [=](int n, const string& str) {
self->send(buddy, n * 2, s + " from " + name); s->send(buddy, n * 2, str + " from " + name);
}, },
on(atom("done")) >> [=] { on(atom("done")) >> [=] {
self->quit(); s->quit();
} }
); );
}; };
...@@ -781,15 +783,15 @@ void test_spawn() { ...@@ -781,15 +783,15 @@ void test_spawn() {
// - the lambda is always executed in the current actor's thread // - the lambda is always executed in the current actor's thread
// but using spawn_next in a message handler could // but using spawn_next in a message handler could
// still cause undefined behavior! // still cause undefined behavior!
auto kr34t0r = [&spawn_next](event_based_actor* self, const string& name, actor pal) { auto kr34t0r = [&spawn_next](event_based_actor* s, const string& name, actor pal) {
if (name == "Joe" && !pal) { if (name == "Joe" && !pal) {
pal = spawn_next("Bob", self); pal = spawn_next("Bob", s);
} }
self->become ( s->become (
others() >> [=] { others() >> [=] {
// forward message and die // forward message and die
self->send_tuple(pal, self->last_dequeued()); s->send_tuple(pal, s->last_dequeued());
self->quit(); s->quit();
} }
); );
}; };
...@@ -832,12 +834,12 @@ void test_spawn() { ...@@ -832,12 +834,12 @@ void test_spawn() {
// create some actors linked to one single actor // create some actors linked to one single actor
// and kill them all through killing the link // and kill them all through killing the link
auto legion = spawn([](event_based_actor* self) { auto legion = spawn([](event_based_actor* s) {
CPPA_PRINT("spawn 100 actors"); CPPA_PRINT("spawn 100 actors");
for (int i = 0; i < 100; ++i) { for (int i = 0; i < 100; ++i) {
self->spawn<event_testee, linked>(); s->spawn<event_testee, linked>();
} }
self->become(others() >> CPPA_UNEXPECTED_MSG_CB()); s->become(others() >> CPPA_UNEXPECTED_MSG_CB());
}); });
self->send_exit(legion, exit_reason::user_shutdown); self->send_exit(legion, exit_reason::user_shutdown);
self->await_all_other_actors_done(); self->await_all_other_actors_done();
...@@ -916,6 +918,8 @@ void test_spawn() { ...@@ -916,6 +918,8 @@ void test_spawn() {
CPPA_CHECKPOINT(); CPPA_CHECKPOINT();
} }
} // namespace <anonymous>
int main() { int main() {
CPPA_TEST(test_spawn); CPPA_TEST(test_spawn);
test_spawn(); test_spawn();
......
...@@ -5,6 +5,8 @@ using namespace std; ...@@ -5,6 +5,8 @@ using namespace std;
using namespace cppa; using namespace cppa;
using namespace cppa::placeholders; using namespace cppa::placeholders;
namespace {
struct sync_mirror : sb_actor<sync_mirror> { struct sync_mirror : sb_actor<sync_mirror> {
behavior init_state; behavior init_state;
...@@ -179,40 +181,39 @@ void test_sync_send() { ...@@ -179,40 +181,39 @@ void test_sync_send() {
self->on_sync_failure([&] { self->on_sync_failure([&] {
CPPA_FAILURE("received: " << to_string(self->last_dequeued())); CPPA_FAILURE("received: " << to_string(self->last_dequeued()));
}); });
self->spawn<monitored + blocking_api>([](blocking_actor* self) { self->spawn<monitored + blocking_api>([](blocking_actor* s) {
CPPA_LOGC_TRACE("NONE", "main$sync_failure_test", "id = " << self->id()); CPPA_LOGC_TRACE("NONE", "main$sync_failure_test", "id = " << s->id());
int invocations = 0; int invocations = 0;
auto foi = self->spawn<float_or_int, linked>(); auto foi = s->spawn<float_or_int, linked>();
self->send(foi, atom("i")); s->send(foi, atom("i"));
self->receive(on_arg_match >> [](int i) { CPPA_CHECK_EQUAL(i, 0); }); s->receive(on_arg_match >> [](int i) { CPPA_CHECK_EQUAL(i, 0); });
self->on_sync_failure([=] { s->on_sync_failure([=] {
CPPA_FAILURE("received: " << to_string(self->last_dequeued())); CPPA_FAILURE("received: " << to_string(s->last_dequeued()));
}); });
self->sync_send(foi, atom("i")).await( s->sync_send(foi, atom("i")).await(
[&](int i) { CPPA_CHECK_EQUAL(i, 0); ++invocations; }, [&](int i) { CPPA_CHECK_EQUAL(i, 0); ++invocations; },
[&](float) { CPPA_UNEXPECTED_MSG(); } [&](float) { CPPA_UNEXPECTED_MSG(); }
); );
self->sync_send(foi, atom("f")).await( s->sync_send(foi, atom("f")).await(
[&](int) { CPPA_UNEXPECTED_MSG(); }, [&](int) { CPPA_UNEXPECTED_MSG(); },
[&](float f) { CPPA_CHECK_EQUAL(f, 0); ++invocations; } [&](float f) { CPPA_CHECK_EQUAL(f, 0.f); ++invocations; }
); );
//self->exec_behavior_stack();
CPPA_CHECK_EQUAL(invocations, 2); CPPA_CHECK_EQUAL(invocations, 2);
CPPA_PRINT("trigger sync failure"); CPPA_PRINT("trigger sync failure");
// provoke invocation of self->handle_sync_failure() // provoke invocation of s->handle_sync_failure()
bool sync_failure_called = false; bool sync_failure_called = false;
bool int_handler_called = false; bool int_handler_called = false;
self->on_sync_failure([&] { s->on_sync_failure([&] {
sync_failure_called = true; sync_failure_called = true;
}); });
self->sync_send(foi, atom("f")).await( s->sync_send(foi, atom("f")).await(
on<int>() >> [&] { on<int>() >> [&] {
int_handler_called = true; int_handler_called = true;
} }
); );
CPPA_CHECK_EQUAL(sync_failure_called, true); CPPA_CHECK_EQUAL(sync_failure_called, true);
CPPA_CHECK_EQUAL(int_handler_called, false); CPPA_CHECK_EQUAL(int_handler_called, false);
self->quit(exit_reason::user_shutdown); s->quit(exit_reason::user_shutdown);
}); });
self->receive ( self->receive (
on_arg_match >> [&](const down_msg& dm) { on_arg_match >> [&](const down_msg& dm) {
...@@ -294,36 +295,36 @@ void test_sync_send() { ...@@ -294,36 +295,36 @@ void test_sync_send() {
CPPA_CHECKPOINT(); CPPA_CHECKPOINT();
// test use case 3 // test use case 3
self->spawn<monitored + blocking_api>([](blocking_actor* self) { // client self->spawn<monitored + blocking_api>([](blocking_actor* s) { // client
auto s = self->spawn<server, linked>(); // server auto serv = s->spawn<server, linked>(); // server
auto w = self->spawn<linked>([](event_based_actor* self) { // worker auto work = s->spawn<linked>([](event_based_actor* w) { // worker
self->become(on(atom("request")) >> []{ return atom("response"); }); w->become(on(atom("request")) >> []{ return atom("response"); });
}); });
// first 'idle', then 'request' // first 'idle', then 'request'
anon_send(s, atom("idle"), w); anon_send(serv, atom("idle"), work);
self->sync_send(s, atom("request")).await( s->sync_send(serv, atom("request")).await(
on(atom("response")) >> [=] { on(atom("response")) >> [=] {
CPPA_CHECKPOINT(); CPPA_CHECKPOINT();
CPPA_CHECK_EQUAL(self->last_sender(), w); CPPA_CHECK_EQUAL(s->last_sender(), work);
}, },
others() >> [&] { others() >> [&] {
CPPA_PRINTERR("unexpected message: " CPPA_PRINTERR("unexpected message: "
<< to_string(self->last_dequeued())); << to_string(s->last_dequeued()));
} }
); );
// first 'request', then 'idle' // first 'request', then 'idle'
auto handle = self->sync_send(s, atom("request")); auto handle = s->sync_send(serv, atom("request"));
send_as(w, s, atom("idle")); send_as(work, serv, atom("idle"));
handle.await( handle.await(
on(atom("response")) >> [=] { on(atom("response")) >> [=] {
CPPA_CHECKPOINT(); CPPA_CHECKPOINT();
CPPA_CHECK_EQUAL(self->last_sender(), w); CPPA_CHECK_EQUAL(s->last_sender(), work);
}, },
others() >> CPPA_UNEXPECTED_MSG_CB() others() >> CPPA_UNEXPECTED_MSG_CB()
); );
self->send(s, "Ever danced with the devil in the pale moonlight?"); s->send(s, "Ever danced with the devil in the pale moonlight?");
// response: {'EXIT', exit_reason::user_shutdown} // response: {'EXIT', exit_reason::user_shutdown}
self->receive_loop(others() >> CPPA_UNEXPECTED_MSG_CB()); s->receive_loop(others() >> CPPA_UNEXPECTED_MSG_CB());
}); });
self->receive ( self->receive (
on_arg_match >> [&](const down_msg& dm) { on_arg_match >> [&](const down_msg& dm) {
...@@ -333,11 +334,15 @@ void test_sync_send() { ...@@ -333,11 +334,15 @@ void test_sync_send() {
); );
} }
} // namespace <anonymous>
int main() { int main() {
CPPA_TEST(test_sync_send); CPPA_TEST(test_sync_send);
test_sync_send(); test_sync_send();
await_all_actors_done(); await_all_actors_done();
CPPA_CHECKPOINT(); CPPA_CHECKPOINT();
shutdown(); shutdown();
// shutdown warning about unused function (only performs compile-time check)
static_cast<void>(compile_time_optional_variant_check);
return CPPA_TEST_RESULT(); return CPPA_TEST_RESULT();
} }
...@@ -36,7 +36,22 @@ using namespace cppa; ...@@ -36,7 +36,22 @@ using namespace cppa;
using namespace cppa::detail; using namespace cppa::detail;
using namespace cppa::placeholders; using namespace cppa::placeholders;
namespace { std::atomic<size_t> s_expensive_copies; }
#define CPPA_CHECK_INVOKED(FunName, Args) \
invoked.clear(); \
if ( !( FunName Args ) || invoked != #FunName ) { \
CPPA_FAILURE("invocation of " #FunName " failed"); \
} else { CPPA_CHECKPOINT(); } static_cast<void>(42)
#define CPPA_CHECK_NOT_INVOKED(FunName, Args) \
invoked.clear(); \
if ( FunName Args || invoked == #FunName ) { \
CPPA_FAILURE(#FunName " erroneously invoked"); \
} else { CPPA_CHECKPOINT(); } static_cast<void>(42)
namespace {
std::atomic<size_t> s_expensive_copies;
struct expensive_copy_struct { struct expensive_copy_struct {
...@@ -57,11 +72,6 @@ inline bool operator==(const expensive_copy_struct& lhs, ...@@ -57,11 +72,6 @@ inline bool operator==(const expensive_copy_struct& lhs,
return lhs.value == rhs.value; return lhs.value == rhs.value;
} }
inline bool operator!=(const expensive_copy_struct& lhs,
const expensive_copy_struct& rhs) {
return !(lhs == rhs);
}
std::string int2str(int i) { std::string int2str(int i) {
return std::to_string(i); return std::to_string(i);
} }
...@@ -75,18 +85,6 @@ optional<int> str2int(const std::string& str) { ...@@ -75,18 +85,6 @@ optional<int> str2int(const std::string& str) {
return none; return none;
} }
#define CPPA_CHECK_INVOKED(FunName, Args) \
invoked.clear(); \
if ( !( FunName Args ) || invoked != #FunName ) { \
CPPA_FAILURE("invocation of " #FunName " failed"); \
} else { CPPA_CHECKPOINT(); } static_cast<void>(42)
#define CPPA_CHECK_NOT_INVOKED(FunName, Args) \
invoked.clear(); \
if ( FunName Args || invoked == #FunName ) { \
CPPA_FAILURE(#FunName " erroneously invoked"); \
} else { CPPA_CHECKPOINT(); } static_cast<void>(42)
struct dummy_receiver : event_based_actor { struct dummy_receiver : event_based_actor {
behavior make_behavior() override { behavior make_behavior() override {
return ( return (
...@@ -455,12 +453,15 @@ void check_drop() { ...@@ -455,12 +453,15 @@ void check_drop() {
CPPA_CHECK(t0.take(0).empty()); CPPA_CHECK(t0.take(0).empty());
} }
} // namespace <anonymous>
int main() { int main() {
CPPA_TEST(test_tuple); CPPA_TEST(test_tuple);
announce<expensive_copy_struct>(&expensive_copy_struct::value); announce<expensive_copy_struct>(&expensive_copy_struct::value);
check_type_list(); check_type_list();
check_default_ctors(); check_default_ctors();
check_guards(); check_guards();
check_many_cases();
check_wildcards(); check_wildcards();
check_move_ops(); check_move_ops();
check_drop(); check_drop();
......
...@@ -35,6 +35,8 @@ ...@@ -35,6 +35,8 @@
using namespace std; using namespace std;
using namespace cppa; using namespace cppa;
namespace {
/****************************************************************************** /******************************************************************************
* simple request/response test * * simple request/response test *
******************************************************************************/ ******************************************************************************/
...@@ -312,6 +314,8 @@ void test_sending_typed_actors() { ...@@ -312,6 +314,8 @@ void test_sending_typed_actors() {
self->send_exit(aut, exit_reason::user_shutdown); self->send_exit(aut, exit_reason::user_shutdown);
} }
} // namespace <anonymous>
/****************************************************************************** /******************************************************************************
* put it all together * * put it all together *
******************************************************************************/ ******************************************************************************/
......
...@@ -19,7 +19,7 @@ struct pseudo_worker { ...@@ -19,7 +19,7 @@ struct pseudo_worker {
pseudo_worker() : m_count(0), m_blocked(true) { } pseudo_worker() : m_count(0), m_blocked(true) { }
void run() { void run [[noreturn]] () {
for (;;) { for (;;) {
if (m_blocked) { if (m_blocked) {
yield(yield_state::blocked); yield(yield_state::blocked);
...@@ -33,7 +33,7 @@ struct pseudo_worker { ...@@ -33,7 +33,7 @@ struct pseudo_worker {
}; };
void coroutine(void* worker) { void coroutine [[noreturn]] (void* worker) {
reinterpret_cast<pseudo_worker*>(worker)->run(); reinterpret_cast<pseudo_worker*>(worker)->run();
} }
......
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