Commit 999cfe25 authored by Dominik Charousset's avatar Dominik Charousset

trivariant => optional_variant

this patch replaces trivariant with optional_variant which can offer the
same semantics when used as optional_variant<void,...>
parent ff852526
......@@ -42,6 +42,7 @@ cppa/detail/memory.hpp
cppa/detail/object_array.hpp
cppa/detail/object_impl.hpp
cppa/detail/opt_impls.hpp
cppa/detail/optional_variant_data.hpp
cppa/detail/pair_member.hpp
cppa/detail/projection.hpp
cppa/detail/pseudo_tuple.hpp
......@@ -124,6 +125,7 @@ cppa/opencl/program.hpp
cppa/opencl/smart_ptr.hpp
cppa/opt.hpp
cppa/option.hpp
cppa/optional_variant.hpp
cppa/partial_function.hpp
cppa/primitive_type.hpp
cppa/primitive_variant.hpp
......@@ -149,7 +151,6 @@ cppa/threadless.hpp
cppa/timeout_definition.hpp
cppa/to_string.hpp
cppa/tpartial_function.hpp
cppa/trivariant.hpp
cppa/tuple_cast.hpp
cppa/type_lookup_table.hpp
cppa/uniform_type_info.hpp
......@@ -304,13 +305,13 @@ unit_testing/test_local_group.cpp
unit_testing/test_match.cpp
unit_testing/test_metaprogramming.cpp
unit_testing/test_opencl.cpp
unit_testing/test_optional_variant.cpp
unit_testing/test_primitive_variant.cpp
unit_testing/test_remote_actor.cpp
unit_testing/test_ripemd_160.cpp
unit_testing/test_serialization.cpp
unit_testing/test_spawn.cpp
unit_testing/test_sync_send.cpp
unit_testing/test_trivariant.cpp
unit_testing/test_tuple.cpp
unit_testing/test_uniform_type.cpp
unit_testing/test_yield_interface.cpp
/******************************************************************************\
* ___ __ *
* /\_ \ __/\ \ *
* \//\ \ /\_\ \ \____ ___ _____ _____ __ *
* \ \ \ \/\ \ \ '__`\ /'___\/\ '__`\/\ '__`\ /'__`\ *
* \_\ \_\ \ \ \ \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/>. *
\******************************************************************************/
#ifndef TRIVARIANT_DATA_HPP
#define TRIVARIANT_DATA_HPP
#include <stdexcept>
#include <type_traits>
#define CPPA_OPTIONAL_VARIANT_DATA_CONCAT(x, y) x ## y
#define CPPA_OPTIONAL_VARIANT_DATA_GETTER(pos) \
inline CPPA_OPTIONAL_VARIANT_DATA_CONCAT(T, pos) & \
get(std::integral_constant<int, pos >) { \
return CPPA_OPTIONAL_VARIANT_DATA_CONCAT(v, pos) ; \
} \
inline const CPPA_OPTIONAL_VARIANT_DATA_CONCAT(T, pos) & \
get(std::integral_constant<int, pos >) const { \
return CPPA_OPTIONAL_VARIANT_DATA_CONCAT(v, pos) ; \
}
namespace cppa { struct none_t; }
namespace cppa { namespace detail {
template<typename T>
struct lift_void { typedef T type; };
template<>
struct lift_void<void> { typedef util::void_type type; };
template<typename T0, typename T1 = util::void_type,
typename T2 = util::void_type, typename T3 = util::void_type,
typename T4 = util::void_type, typename T5 = util::void_type,
typename T6 = util::void_type, typename T7 = util::void_type,
typename T8 = util::void_type, typename T9 = util::void_type>
struct optional_variant_data {
union {
T0 v0; T1 v1; T2 v2; T3 v3; T4 v4;
T5 v5; T6 v6; T7 v7; T8 v8; T9 v9;
};
optional_variant_data() { }
template<int Id, typename U>
optional_variant_data(std::integral_constant<int, Id> token, U&& arg) {
cr(get(token), std::forward<U>(arg));
}
~optional_variant_data() { }
CPPA_OPTIONAL_VARIANT_DATA_GETTER(0)
CPPA_OPTIONAL_VARIANT_DATA_GETTER(1)
CPPA_OPTIONAL_VARIANT_DATA_GETTER(2)
CPPA_OPTIONAL_VARIANT_DATA_GETTER(3)
CPPA_OPTIONAL_VARIANT_DATA_GETTER(4)
CPPA_OPTIONAL_VARIANT_DATA_GETTER(5)
CPPA_OPTIONAL_VARIANT_DATA_GETTER(6)
CPPA_OPTIONAL_VARIANT_DATA_GETTER(7)
CPPA_OPTIONAL_VARIANT_DATA_GETTER(8)
CPPA_OPTIONAL_VARIANT_DATA_GETTER(9)
private:
template<typename M, typename U>
inline void cr(M& member, U&& arg) {
new (&member) M (std::forward<U>(arg));
}
};
struct optional_variant_data_destructor {
inline void operator()() const { }
inline void operator()(const none_t&) const { }
template<typename T>
inline void operator()(T& storage) const { storage.~T(); }
};
} } // namespace cppa::detail
#endif // TRIVARIANT_DATA_HPP
......@@ -359,7 +359,6 @@ class local_actor : public extend<actor>::with<memory_cached> {
std::function<void()> m_sync_failure_handler;
std::function<void()> m_sync_timeout_handler;
/** @endcond */
};
......
......@@ -12,7 +12,7 @@ endmacro()
add_unit_test(ripemd_160)
add_unit_test(atom)
add_unit_test(trivariant)
add_unit_test(optional_variant)
add_unit_test(metaprogramming)
add_unit_test(intrusive_containers)
add_unit_test(serialization)
......
#include <iostream>
#include <functional>
#include "test.hpp"
#include "cppa/cppa.hpp"
#include "cppa/optional_variant.hpp"
using namespace std;
using namespace cppa;
namespace { std::atomic<size_t> some_struct_instances; }
struct some_struct {
some_struct() { ++some_struct_instances; }
some_struct(const some_struct&) { ++some_struct_instances; }
~some_struct() { --some_struct_instances; }
};
struct int_visitor {
int operator()(none_t) const { return -1; }
int operator()(int i) const { return i; }
int operator()(const some_struct&) const { return 0; }
};
using dlimits = std::numeric_limits<double>;
struct double_visitor {
double operator()(none_t) const { return dlimits::signaling_NaN(); }
double operator()(void) const { return dlimits::quiet_NaN(); }
double operator()(int i) const { return i; }
double operator()(float f) const { return f; }
double operator()(double d) const { return d; }
};
int main() {
CPPA_TEST(test_optional_variant);
/* run tets using primitive types */ {
using tri_type = optional_variant<void, int, double, float>;
tri_type t0;
tri_type t1{util::void_type{}};
tri_type t2{0};
tri_type t3{0.0};
tri_type t4{0.0f};
CPPA_CHECK(!t0);
CPPA_CHECK(t1 && t1.is<void>());
CPPA_CHECK(t2.is<int>());
CPPA_CHECK(!t2.is<double>());
CPPA_CHECK(!t2.is<float>());
CPPA_CHECK_EQUAL(get<int>(t2), 0);
get_ref<int>(t2) = 42;
CPPA_CHECK_EQUAL(get<int>(t2), 42);
CPPA_CHECK(!t3.is<int>());
CPPA_CHECK(t3.is<double>());
CPPA_CHECK(!t3.is<float>());
CPPA_CHECK_EQUAL(get<double>(t3), 0.0);
get_ref<double>(t3) = 4.2;
CPPA_CHECK_EQUAL(get<double>(t3), 4.2);
CPPA_CHECK(!t4.is<int>());
CPPA_CHECK(!t4.is<double>());
CPPA_CHECK(t4.is<float>());
CPPA_CHECK_EQUAL(get<float>(t4), 0.0f);
get_ref<float>(t4) = 2.3f;
CPPA_CHECK_EQUAL(get<float>(t4), 2.3f);
double_visitor dv;
auto v = apply_visitor(dv, t0);
CPPA_CHECK(v != v); // only true if v is NaN
v = apply_visitor(dv, t1);
CPPA_CHECK(v != v); // only true if v is NaN
CPPA_CHECK_EQUAL(apply_visitor(dv, t2), 42.0);
CPPA_CHECK_EQUAL(apply_visitor(dv, t3), 4.2);
// converting 2.3f to double is not exactly 2.3
CPPA_CHECK_EQUAL(apply_visitor(dv, t4), static_cast<double>(2.3f));
t4 = 1;
CPPA_CHECK(t4.is<int>() && get<int>(t4) == 1);
}
/* run tests using user-defined types */ {
using tri_type = optional_variant<int, some_struct>;
tri_type t0;
tri_type t1{42};
CPPA_CHECK_EQUAL(some_struct_instances.load(), 0);
tri_type t2{some_struct{}};
CPPA_CHECK_EQUAL(some_struct_instances.load(), 1);
CPPA_CHECK(!t0);
CPPA_CHECK(t1 && t1.is<int>() && get<int>(t1) == 42);
CPPA_CHECK(t2 && t2.is<some_struct>());
int_visitor iVisit;
CPPA_CHECK_EQUAL(apply_visitor(iVisit, t0), -1);
CPPA_CHECK_EQUAL(apply_visitor(iVisit, t1), 42);
CPPA_CHECK_EQUAL(apply_visitor(iVisit, t2), 0);
}
CPPA_CHECK_EQUAL(some_struct_instances.load(), 0);
return CPPA_TEST_RESULT();
}
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