Commit e238cff1 authored by Dominik Charousset's avatar Dominik Charousset

Replace optional with maybe

parent 585cd8b5
Subproject commit 2c45d8c1c2b934e062baf378809201ac66d169a7
Subproject commit b300db01ac8bfbb396b62163fe36da39a8f12469
Subproject commit 38bcdedf7df5536899dd4373969e6653380d2a86
Subproject commit 08cc54612466e68f35b9b2f6ecaa8853914d3574
......@@ -179,7 +179,7 @@ behavior server(broker* self, const actor& buddy) {
};
}
optional<uint16_t> as_u16(const std::string& str) {
maybe<uint16_t> as_u16(const std::string& str) {
return static_cast<uint16_t>(stoul(str));
}
......
......@@ -67,7 +67,7 @@ behavior server(broker* self) {
};
}
optional<uint16_t> as_u16(const std::string& str) {
maybe<uint16_t> as_u16(const std::string& str) {
return static_cast<uint16_t>(stoul(str));
}
......
......@@ -168,7 +168,7 @@ string trim(std::string s) {
}
// tries to convert `str` to an int
optional<int> toint(const string& str) {
maybe<int> toint(const string& str) {
char* end;
auto result = static_cast<int>(strtol(str.c_str(), &end, 10));
if (end == str.c_str() + str.size()) {
......@@ -178,12 +178,12 @@ optional<int> toint(const string& str) {
}
// converts "+" to the atom '+' and "-" to the atom '-'
optional<atom_value> plus_or_minus(const string& str) {
maybe<atom_value> plus_or_minus(const string& str) {
if (str == "+") {
return optional<atom_value>{plus_atom::value};
return maybe<atom_value>{plus_atom::value};
}
if (str == "-") {
return optional<atom_value>{minus_atom::value};
return maybe<atom_value>{minus_atom::value};
}
return none;
}
......
......@@ -248,7 +248,7 @@ public:
}
// Tries to run a custom exception handler for `eptr`.
optional<uint32_t> handle(const std::exception_ptr& eptr);
maybe<uint32_t> handle(const std::exception_ptr& eptr);
protected:
virtual bool link_impl(linking_operation op, const actor_addr& other);
......
......@@ -25,7 +25,7 @@
#include <typeinfo>
#include <exception>
#include "caf/optional.hpp"
#include "caf/maybe.hpp"
namespace caf {
......@@ -70,7 +70,7 @@ public:
/// Note that the first handler to handle `eptr` "wins" and no other
/// handler will be invoked.
/// @returns The exit reason the actor should use.
virtual optional<uint32_t> handle_exception(const std::exception_ptr& eptr);
virtual maybe<uint32_t> handle_exception(const std::exception_ptr& eptr);
/// Executed if the actor finished execution with given `reason`.
/// The default implementation does nothing.
......
......@@ -93,7 +93,7 @@ public:
}
/// Runs this handler and returns its (optional) result.
inline optional<message> operator()(message& arg) {
inline maybe<message> operator()(message& arg) {
return (impl_) ? impl_->invoke(arg) : none;
}
......
......@@ -61,6 +61,7 @@
#if defined(__clang__)
# define CAF_CLANG
# define CAF_DEPRECATED __attribute__((__deprecated__))
# define CAF_DEPRECATED_MSG(msg) __attribute__((__deprecated__(msg)))
# define CAF_PUSH_WARNINGS \
_Pragma("clang diagnostic push") \
_Pragma("clang diagnostic ignored \"-Wall\"") \
......@@ -108,6 +109,7 @@
#elif defined(__GNUC__)
# define CAF_GCC
# define CAF_DEPRECATED __attribute__((__deprecated__))
# define CAF_DEPRECATED_MSG(msg) __attribute__((__deprecated__(msg)))
# define CAF_PUSH_WARNINGS
# define CAF_PUSH_NON_VIRTUAL_DTOR_WARNING \
_Pragma("GCC diagnostic push") \
......@@ -123,6 +125,7 @@
#elif defined(_MSC_VER)
# define CAF_MSVC
# define CAF_DEPRECATED
# define CAF_DEPRECATED_MSG(msg)
# define CAF_PUSH_WARNINGS
# define CAF_PUSH_NON_VIRTUAL_DTOR_WARNING
# define CAF_POP_WARNINGS
......
......@@ -25,7 +25,7 @@
#include "caf/none.hpp"
#include "caf/variant.hpp"
#include "caf/optional.hpp"
#include "caf/maybe.hpp"
#include "caf/match_case.hpp"
#include "caf/make_counted.hpp"
#include "caf/intrusive_ptr.hpp"
......@@ -49,7 +49,7 @@
namespace caf {
class message_handler;
using bhvr_invoke_result = optional<message>;
using bhvr_invoke_result = maybe<message>;
} // namespace caf
......
......@@ -25,7 +25,7 @@
#include <utility>
#include <algorithm>
#include "caf/optional.hpp"
#include "caf/maybe.hpp"
#include "caf/config.hpp"
#include "caf/behavior.hpp"
......
......@@ -99,7 +99,7 @@ constexpr int impl_id() {
? 2
: (is_stl_pair<T>::value
? 3
: (detail::is_optional<T>::value
: (detail::is_maybe<T>::value
? 4
: (std::is_array<T>::value
? 5
......@@ -161,7 +161,7 @@ private:
}
template <class T>
void simpl(const optional<T>& val, serializer* s, opt_impl) const {
void simpl(const maybe<T>& val, serializer* s, opt_impl) const {
uint8_t flag = val ? 1 : 0;
s->write_value(flag);
if (val) {
......@@ -218,7 +218,7 @@ private:
}
template <class T>
void dimpl(optional<T>& val, deserializer* d, opt_impl) const {
void dimpl(maybe<T>& val, deserializer* d, opt_impl) const {
auto flag = d->read<uint8_t>();
if (flag != 0) {
T tmp;
......
......@@ -22,7 +22,7 @@
#include "caf/none.hpp"
#include "caf/unit.hpp"
#include "caf/optional.hpp"
#include "caf/maybe.hpp"
#include "caf/skip_message.hpp"
#include "caf/static_visitor.hpp"
#include "caf/response_promise.hpp"
......@@ -60,17 +60,17 @@ struct optional_message_visitor_enable_tpl {
none_t,
unit_t,
skip_message_t,
optional<skip_message_t>
maybe<skip_message_t>
>::value
&& ! is_message_id_wrapper<T>::value
&& ! is_response_promise<T>::value;
};
class optional_message_visitor : public static_visitor<optional<message>> {
class optional_message_visitor : public static_visitor<maybe<message>> {
public:
optional_message_visitor() = default;
using opt_msg = optional<message>;
using opt_msg = maybe<message>;
inline opt_msg operator()(const none_t&) const {
return none;
......@@ -84,7 +84,7 @@ public:
return message{};
}
inline opt_msg operator()(const optional<skip_message_t>& val) const {
inline opt_msg operator()(const maybe<skip_message_t>& val) const {
if (val) {
return none;
}
......
......@@ -22,7 +22,7 @@
#include <istream>
#include "caf/optional.hpp"
#include "caf/maybe.hpp"
#include "caf/parse_config.hpp"
namespace caf {
......@@ -35,7 +35,7 @@ namespace detail {
/// @param consumer Callback consuming generated key-value pairs.
void parse_ini(std::istream& raw_data,
config_consumer consumer,
optional<std::ostream&> errors = none);
maybe<std::ostream&> errors = none);
} // namespace detail
} // namespace caf
......
......@@ -24,7 +24,7 @@
#include <functional>
#include <type_traits>
#include "caf/optional.hpp"
#include "caf/maybe.hpp"
#include "caf/fwd.hpp"
......@@ -266,14 +266,14 @@ public:
static constexpr bool value = decltype(check<T>(0))::value;
};
/// Returns either `T` or `T::type` if `T` is an option.
/// Returns either `T` or `T::type` if `T` is a `maybe`.
template <class T>
struct rm_optional {
struct rm_maybe {
using type = T;
};
template <class T>
struct rm_optional<optional<T>> {
struct rm_maybe<maybe<T>> {
using type = T;
};
......@@ -453,12 +453,12 @@ struct type_at<0, T0, Ts...> {
};
template <class T>
struct is_optional : std::false_type {
struct is_maybe : std::false_type {
// no members
};
template <class T>
struct is_optional<optional<T>> : std::true_type {
struct is_maybe<maybe<T>> : std::true_type {
// no members
};
......
......@@ -382,7 +382,7 @@ public:
functor_attachable(F arg) : functor_(std::move(arg)) {
// nop
}
optional<uint32_t> handle_exception(const std::exception_ptr& eptr) {
maybe<uint32_t> handle_exception(const std::exception_ptr& eptr) {
return functor_(eptr);
}
};
......@@ -605,7 +605,7 @@ public:
bool awaits(message_id response_id) const;
optional<pending_response&> find_pending_response(message_id mid);
maybe<pending_response&> find_pending_response(message_id mid);
void set_response_handler(message_id response_id, behavior bhvr);
......
......@@ -21,7 +21,7 @@
#define CAF_MATCH_CASE_HPP
#include "caf/none.hpp"
#include "caf/optional.hpp"
#include "caf/maybe.hpp"
#include "caf/skip_message.hpp"
#include "caf/match_case.hpp"
......@@ -53,7 +53,7 @@ public:
virtual ~match_case();
virtual result invoke(optional<message>&, message&) = 0;
virtual result invoke(maybe<message>&, message&) = 0;
inline uint32_t type_token() const {
return token_;
......@@ -86,7 +86,7 @@ T& unopt(T& v) {
}
template <class T>
T& unopt(optional<T>& v) {
T& unopt(maybe<T>& v) {
return *v;
}
......@@ -101,7 +101,7 @@ struct has_none {
}
template <class T, class... Ts>
bool operator()(const optional<T>& x, const Ts&... xs) const {
bool operator()(const maybe<T>& x, const Ts&... xs) const {
return ! x || (*this)(xs...);
}
};
......@@ -192,7 +192,7 @@ public:
// nop
}
match_case::result invoke(optional<message>& res, message& msg) override {
match_case::result invoke(maybe<message>& res, message& msg) override {
intermediate_tuple it;
detail::meta_elements<pattern> ms;
// check if try_match() reports success
......@@ -240,7 +240,7 @@ public:
// nop
}
match_case::result invoke(optional<message>& res, message&) override {
match_case::result invoke(maybe<message>& res, message&) override {
lfinvoker<std::is_same<result_type, void>::value, F> fun{fun_};
auto fun_res = fun();
detail::optional_message_visitor omv;
......@@ -273,7 +273,7 @@ public:
// however, dealing with all the template parameters in a debugger
// is just dreadful; this "hack" essentially hides all the ugly
// template boilterplate types when debugging CAF applications
match_case::result invoke(optional<message>& res, message& msg) override {
match_case::result invoke(maybe<message>& res, message& msg) override {
struct storage {
storage() : valid(false) {
// nop
......@@ -338,13 +338,13 @@ public:
static constexpr uint32_t static_type_token =
detail::make_type_token_from_list<Pattern>();
// Let F be "R (Ts...)" then match_case<F...> returns optional<R>
// Let F be "R (Ts...)" then match_case<F...> returns maybe<R>
// unless R is void in which case bool is returned
using optional_result_type =
typename std::conditional<
std::is_same<result_type, void>::value,
optional<unit_t>,
optional<result_type>
maybe<unit_t>,
maybe<result_type>
>::type;
// Needed for static type checking when assigning to a typed behavior.
......
/******************************************************************************
* ____ _ _____ *
* / ___| / \ | ___| C++ *
* | | / _ \ | |_ Actor *
* | |___ / ___ \| _| Framework *
* \____/_/ \_|_| *
* *
* Copyright (C) 2011 - 2015 *
* Dominik Charousset <dominik.charousset (at) haw-hamburg.de> *
* *
* Distributed under the terms and conditions of the BSD 3-Clause License or *
* (at your option) under the terms and conditions of the Boost Software *
* License 1.0. See accompanying files LICENSE and LICENSE_ALTERNATIVE. *
* *
* If you did not receive a copy of the license files, see *
* http://opensource.org/licenses/BSD-3-Clause and *
* http://www.boost.org/LICENSE_1_0.txt. *
******************************************************************************/
#ifndef CAF_MAYBE_HPP
#define CAF_MAYBE_HPP
#include <new>
#include <utility>
#include <system_error>
#include "caf/none.hpp"
#include "caf/unit.hpp"
#include "caf/config.hpp"
#include "caf/detail/safe_equal.hpp"
namespace caf {
/// Represents a computation returning either `T` or `std::error_condition`.
/// Note that the error condition might be default-constructed. In this case,
/// a `maybe` represents simply `none`. Hence, this type has three possible
/// states:
/// - Enganged (holds a `T`)
/// + `valid() == true`
/// + `is_none() == false`
/// + `has_error() == false`
/// - Not engaged without actual error (default-constructed `error_condition`)
/// + `valid() == false`
/// + `is_none() == true`
/// + `has_error() == false`
/// - Not engaged with error
/// + `valid() == false`
/// + `is_none() == false`
/// + `has_error() == true`
template <class T>
class maybe {
public:
using type = typename std::remove_reference<T>::type;
using reference = type&;
using const_reference = const type&;
using pointer = type*;
using const_pointer = const type*;
using error_type = std::error_condition;
/// The type used for storing values.
using storage =
typename std::conditional<
std::is_reference<T>::value,
std::reference_wrapper<type>,
T
>::type;
/// Creates an instance representing an error.
maybe(error_type err) {
cr_error(std::move(err));
}
/// Creates an instance representing `value`.
maybe(T value) {
cr_moved_value(value);
}
/// Creates an empty instance.
maybe() {
cr_error(error_type{});
}
/// Creates an empty instance.
maybe(const none_t&) {
cr_error(error_type{});
}
maybe(const maybe& other) {
if (other.valid_)
cr_value(other.value_);
else
cr_error(other.error_);
}
maybe(maybe&& other) : valid_(other.valid_) {
if (other.valid_)
cr_moved_value(other.value_);
else
cr_error(std::move(other.error_));
}
~maybe() {
destroy();
}
maybe& operator=(const none_t&) {
if (valid_) {
destroy();
cr_error(error_type{});
} else if (error_) {
error_ = error_type{};
}
return *this;
}
maybe& operator=(T value) {
if (! valid_) {
destroy();
cr_moved_value(value);
} else {
assign_moved_value(value);
}
return *this;
}
maybe& operator=(error_type err) {
if (valid_) {
destroy();
cr_error(std::move(err));
} else {
error_ = std::move(err);
}
return *this;
}
maybe& operator=(const maybe& other) {
if (valid_ != other.valid_) {
destroy();
if (other.valid_)
cr_value(other.value_);
else
cr_error(other.error_);
} else if (valid_) {
value_ = other.value_;
} else {
error_ = other.error_;
}
return *this;
}
maybe& operator=(maybe&& other) {
if (valid_ != other.valid_) {
destroy();
if (other.valid_)
cr_moved_value(other.value_);
else
cr_error(std::move(other.error_));
} else if (valid_) {
value_ = std::move(other.value_);
} else {
error_ = std::move(other.error_);
}
return *this;
}
/// Queries whether this instance holds a value.
bool valid() const {
return valid_;
}
/// Returns `valid()`.
explicit operator bool() const {
return valid();
}
/// Returns `! valid()`.
bool operator!() const {
return ! valid();
}
/// Returns the value.
reference get() {
CAF_ASSERT(valid());
return value_;
}
/// Returns the value.
const_reference get() const {
CAF_ASSERT(valid());
return value_;
}
/// Returns the value.
reference operator*() {
return get();
}
/// Returns the value.
const_reference operator*() const {
return get();
}
/// Returns a pointer to the value.
pointer operator->() {
return &get();
}
/// Returns a pointer to the value.
const_pointer operator->() const {
return &get();
}
/// Returns whether this object holds a non-default `std::error_condition`.
bool has_error() const {
return ! valid() && static_cast<bool>(error());
}
/// Returns whether this objects holds neither a value nor an actual error.
bool is_none() const {
return ! valid() && static_cast<bool>(error()) == false;
}
/// Returns the error.
const error_type& error() const {
CAF_ASSERT(! valid());
return error_;
}
private:
void destroy() {
if (valid_)
value_.~storage();
else
error_.~error_type();
}
void cr_moved_value(reference x) {
// convert to rvalue if possible
using fwd_type =
typename std::conditional<
! std::is_reference<T>::value,
type&&,
type&
>::type;
valid_ = true;
new (&value_) storage(static_cast<fwd_type>(x));
}
void assign_moved_value(reference x) {
using fwd_type =
typename std::conditional<
! std::is_reference<T>::value,
type&&,
type&
>::type;
value_ = static_cast<fwd_type>(x);
}
template <class V>
void cr_value(V&& x) {
valid_ = true;
new (&value_) storage(std::forward<V>(x));
}
void cr_error(std::error_condition ec) {
valid_ = false;
new (&error_) error_type(std::move(ec));
}
bool valid_;
union {
storage value_;
error_type error_;
};
};
/// Returns `true` if both objects represent either the same
/// value or the same error, `false` otherwise.
/// @relates maybe
template <class T, typename U>
bool operator==(const maybe<T>& lhs, const maybe<U>& rhs) {
if (lhs)
return (rhs) ? detail::safe_equal(*lhs, *rhs) : false;
if (! rhs)
return lhs.error() == rhs.error();
return false;
}
/// Returns `true` if `lhs` is valid and its value is equal to `rhs`.
template <class T, typename U>
bool operator==(const maybe<T>& lhs, const U& rhs) {
return (lhs) ? *lhs == rhs : false;
}
/// Returns `true` if `rhs` is valid and its value is equal to `lhs`.
/// @relates maybe
template <class T, typename U>
bool operator==(const T& lhs, const maybe<U>& rhs) {
return rhs == lhs;
}
/// Returns `true` if the objects represent different
/// values or errors, `false` otherwise.
/// @relates maybe
template <class T, typename U>
bool operator!=(const maybe<T>& lhs, const maybe<U>& rhs) {
return !(lhs == rhs);
}
/// Returns `true` if `lhs` is invalid or its value is not equal to `rhs`.
/// @relates maybe
template <class T, typename U>
bool operator!=(const maybe<T>& lhs, const U& rhs) {
return !(lhs == rhs);
}
/// Returns `true` if `rhs` is invalid or its value is not equal to `lhs`.
/// @relates maybe
template <class T, typename U>
bool operator!=(const T& lhs, const maybe<U>& rhs) {
return !(lhs == rhs);
}
/// Returns `! val.valid() && val.error() == err`.
/// @relates maybe
template <class T>
bool operator==(const maybe<T>& val, const std::error_condition& err) {
return ! val.valid() && val.error() == err;
}
/// Returns `! val.valid() && val.error() == err`.
/// @relates maybe
template <class T>
bool operator==(const std::error_condition& err, const maybe<T>& val) {
return val == err;
}
/// Returns `val.valid() || val.error() != err`.
/// @relates maybe
template <class T>
bool operator!=(const maybe<T>& val, const std::error_condition& err) {
return ! (val == err);
}
/// Returns `val.valid() || val.error() != err`.
/// @relates maybe
template <class T>
bool operator!=(const std::error_condition& err, const maybe<T>& val) {
return ! (val == err);
}
/// Returns `val.is_none()`.
/// @relates maybe
template <class T>
bool operator==(const maybe<T>& val, const none_t&) {
return val.is_none();
}
/// Returns `val.is_none()`.
/// @relates maybe
template <class T>
bool operator==(const none_t&, const maybe<T>& val) {
return val.is_none();
}
/// Returns `! val.is_none()`.
/// @relates maybe
template <class T>
bool operator!=(const maybe<T>& val, const none_t&) {
return ! val.is_none();
}
/// Returns `! val.is_none()`.
/// @relates maybe
template <class T>
bool operator!=(const none_t&, const maybe<T>& val) {
return ! val.is_none();
}
} // namespace caf
#endif // CAF_MAYBE_HPP
......@@ -122,7 +122,7 @@ public:
}
/// Returns `handler(*this)`.
optional<message> apply(message_handler handler);
maybe<message> apply(message_handler handler);
/// Filters this message by applying slices of it to `handler` and returns
/// the remaining elements of this operation. Slices are generated in the
......
......@@ -99,7 +99,7 @@ public:
}
/// @copydoc message::apply
optional<message> apply(message_handler handler);
maybe<message> apply(message_handler handler);
/// Removes all elements from the buffer.
void clear();
......
......@@ -87,7 +87,7 @@ public:
void assign(message_handler other);
/// Runs this handler and returns its (optional) result.
inline optional<message> operator()(message& arg) {
inline maybe<message> operator()(message& arg) {
return (impl_) ? impl_->invoke(arg) : none;
}
......
......@@ -90,8 +90,8 @@ constexpr auto arg_match = detail::boxed<detail::arg_match_t>::type();
/// Generates function objects from a binary predicate and a value.
template <class T, typename BinaryPredicate>
std::function<optional<T>(const T&)> guarded(BinaryPredicate p, T value) {
return [=](const T& other) -> optional<T> {
std::function<maybe<T>(const T&)> guarded(BinaryPredicate p, T value) {
return [=](const T& other) -> maybe<T> {
if (p(other, value)) {
return value;
}
......@@ -120,7 +120,7 @@ unit_t to_guard(const detail::wrapped<T>&) {
}
template <class T>
std::function<optional<typename detail::strip_and_convert<T>::type>(
std::function<maybe<typename detail::strip_and_convert<T>::type>(
const typename detail::strip_and_convert<T>::type&)>
to_guard(const T& value,
typename std::enable_if<! detail::is_callable<T>::value>::type* = 0) {
......
......@@ -20,307 +20,14 @@
#ifndef CAF_OPTIONAL_HPP
#define CAF_OPTIONAL_HPP
#include <new>
#include <utility>
#include "caf/none.hpp"
#include "caf/unit.hpp"
#include "caf/config.hpp"
#include "caf/detail/safe_equal.hpp"
#include "caf/maybe.hpp"
namespace caf {
/// Represents an optional value of `T`.
template <class T>
class optional {
public:
/// Typdef for `T`.
using type = T;
/// Creates an empty instance with `valid() == false`.
optional(const none_t& = none) : valid_(false) {
// nop
}
/// Creates an valid instance from `value`.
optional(T value) : valid_(false) {
cr(std::move(value));
}
template <class U>
optional(const optional<U>& other) : valid_(false) {
if (other.valid()) {
cr(other.get());
}
}
template <class U>
optional(optional<U>&& other) : valid_(false) {
if (other.valid()) {
cr(std::move(other.get()));
}
}
optional(const optional& other) : valid_(false) {
if (other.valid_) {
cr(other.value_);
}
}
optional(optional&& other) : valid_(false) {
if (other.valid_) {
cr(std::move(other.value_));
}
}
~optional() {
destroy();
}
optional& operator=(const optional& other) {
if (valid_) {
if (other.valid_) value_ = other.value_;
else destroy();
}
else if (other.valid_) {
cr(other.value_);
}
return *this;
}
optional& operator=(optional&& other) {
if (valid_) {
if (other.valid_) value_ = std::move(other.value_);
else destroy();
}
else if (other.valid_) {
cr(std::move(other.value_));
}
return *this;
}
/// Queries whether this instance holds a value.
bool valid() const {
return valid_;
}
/// Returns `!valid()`.
bool empty() const {
return ! valid_;
}
/// Returns `valid()`.
explicit operator bool() const {
return valid();
}
/// Returns `!valid()`.
bool operator!() const {
return ! valid();
}
/// Returns the value.
T& operator*() {
CAF_ASSERT(valid());
return value_;
}
/// Returns the value.
const T& operator*() const {
CAF_ASSERT(valid());
return value_;
}
/// Returns the value.
const T* operator->() const {
CAF_ASSERT(valid());
return &value_;
}
/// Returns the value.
T* operator->() {
CAF_ASSERT(valid());
return &value_;
}
/// Returns the value.
T& get() {
CAF_ASSERT(valid());
return value_;
}
/// Returns the value.
const T& get() const {
CAF_ASSERT(valid());
return value_;
}
/// Returns the value if `valid()`, otherwise returns `default_value`.
const T& get_or_else(const T& default_value) const {
return valid() ? get() : default_value;
}
private:
void destroy() {
if (valid_) {
value_.~T();
valid_ = false;
}
}
template <class V>
void cr(V&& value) {
CAF_ASSERT(! valid());
valid_ = true;
new (&value_) T(std::forward<V>(value));
}
bool valid_;
union { T value_; };
};
/// Template specialization to allow `optional`
/// to hold a reference rather than an actual value.
template <class T>
class optional<T&> {
public:
using type = T;
optional(const none_t& = none) : value_(nullptr) {
// nop
}
optional(T& value) : value_(&value) {
// nop
}
template <class U>
optional(const optional<U>& value) {
if (value)
value_ = &value.get();
else
value_ = nullptr;
}
optional(const optional& other) = default;
optional& operator=(const optional& other) = default;
bool valid() const {
return value_ != nullptr;
}
bool empty() const {
return ! valid();
}
explicit operator bool() const {
return valid();
}
bool operator!() const {
return ! valid();
}
T& operator*() {
CAF_ASSERT(valid());
return *value_;
}
const T& operator*() const {
CAF_ASSERT(valid());
return *value_;
}
T* operator->() {
CAF_ASSERT(valid());
return value_;
}
const T* operator->() const {
CAF_ASSERT(valid());
return value_;
}
T& get() {
CAF_ASSERT(valid());
return *value_;
}
const T& get() const {
CAF_ASSERT(valid());
return *value_;
}
const T& get_or_else(const T& default_value) const {
if (valid()) return get();
return default_value;
}
private:
T* value_;
};
/// @relates optional
template <class T, typename U>
bool operator==(const optional<T>& lhs, const optional<U>& rhs) {
if ((lhs) && (rhs)) {
return detail::safe_equal(*lhs, *rhs);
}
return ! lhs && ! rhs;
}
/// @relates optional
template <class T, typename U>
bool operator==(const optional<T>& lhs, const U& rhs) {
return (lhs) ? *lhs == rhs : false;
}
/// @relates optional
template <class T, typename U>
bool operator==(const T& lhs, const optional<U>& rhs) {
return rhs == lhs;
}
/// @relates optional
template <class T, typename U>
bool operator!=(const optional<T>& lhs, const optional<U>& rhs) {
return !(lhs == rhs);
}
/// @relates optional
template <class T, typename U>
bool operator!=(const optional<T>& lhs, const U& rhs) {
return !(lhs == rhs);
}
/// @relates optional
template <class T, typename U>
bool operator!=(const T& lhs, const optional<U>& rhs) {
return !(lhs == rhs);
}
/// @relates optional
template <class T>
bool operator==(const optional<T>& val, const none_t&) {
return ! val.valid();
}
/// @relates optional
template <class T>
bool operator==(const none_t&, const optional<T>& val) {
return ! val.valid();
}
/// @relates optional
template <class T>
bool operator!=(const optional<T>& lhs, const none_t& rhs) {
return !(lhs == rhs);
}
/// @relates optional
// <backward_compatibility version="0.14">
template <class T>
bool operator!=(const none_t& lhs, const optional<T>& rhs) {
return !(lhs == rhs);
}
using optional CAF_DEPRECATED_MSG("replaced by maybe<T>") = maybe<T>;
// </backward_compatibility>
} // namespace caf
......
......@@ -25,7 +25,7 @@
#include <algorithm>
#include "caf/variant.hpp"
#include "caf/optional.hpp"
#include "caf/maybe.hpp"
namespace caf {
......@@ -45,7 +45,7 @@ using config_consumer = std::function<void (std::string, config_value)>;
/// @param format Configuration format such as INI.
/// @param errors Output streams for error messages.
void parse_config(std::istream& input_stream, config_format format,
optional<std::ostream&> errors = none);
maybe<std::ostream&> errors = none);
/// Read configuration from `file_name` using given `format` or try to
/// deduce file format automatically if `cf == none`.
......@@ -53,8 +53,8 @@ void parse_config(std::istream& input_stream, config_format format,
/// @param cf Forces the parser to use a specific file format unless `none`.
/// @param errors Output streams for error messages.
void parse_config(const std::string& file_name,
optional<config_format> cf = none,
optional<std::ostream&> errors = none);
maybe<config_format> cf = none,
maybe<std::ostream&> errors = none);
} // namespace caf
......
......@@ -166,7 +166,7 @@ inline std::string convert_to_str(std::string value) {
// string projection
template <class T>
caf::optional<T> spro(const std::string& str) {
caf::maybe<T> spro(const std::string& str) {
T value;
std::istringstream iss(str);
if (iss >> value) {
......
......@@ -23,7 +23,7 @@
#include <string>
#include "caf/fwd.hpp"
#include "caf/optional.hpp"
#include "caf/maybe.hpp"
#include "caf/uniform_type_info.hpp"
namespace std {
......@@ -61,7 +61,7 @@ std::string to_string(const mailbox_element& what);
/// @relates optional
template <class T>
std::string to_string(const optional<T>& what) {
std::string to_string(const maybe<T>& what) {
if (! what) {
return "none";
}
......@@ -77,7 +77,7 @@ uniform_value from_string_impl(const std::string& what);
/// Convenience function that tries to deserializes a value from
/// `what` and converts the result to `T`.
template <class T>
optional<T> from_string(const std::string& what) {
maybe<T> from_string(const std::string& what) {
auto uti = uniform_typeid<T>();
auto uv = from_string_impl(what);
if (! uv || uv->ti != uti) {
......
......@@ -246,7 +246,7 @@ std::set<std::string> abstract_actor::message_types() const {
return std::set<std::string>{};
}
optional<uint32_t> abstract_actor::handle(const std::exception_ptr& eptr) {
maybe<uint32_t> abstract_actor::handle(const std::exception_ptr& eptr) {
{ // lifetime scope of guard
guard_type guard{mtx_};
for (auto i = attachables_head_.get(); i != nullptr; i = i->next.get()) {
......
......@@ -244,7 +244,7 @@ void printer_loop(blocking_actor* self) {
sink_handle global_redirect;
data_map data;
auto get_data = [&](const actor_addr& addr, bool insert_missing)
-> optional<actor_data&> {
-> maybe<actor_data&> {
if (addr == invalid_actor_addr)
return none;
auto i = data.find(addr);
......@@ -256,7 +256,7 @@ void printer_loop(blocking_actor* self) {
return i->second;
return none;
};
auto flush = [&](optional<actor_data&> what, bool forced) {
auto flush = [&](maybe<actor_data&> what, bool forced) {
if (! what)
return;
auto& line = what->current_line;
......
......@@ -30,7 +30,7 @@ attachable::token::token(size_t typenr, const void* vptr)
// nop
}
optional<uint32_t> attachable::handle_exception(const std::exception_ptr&) {
maybe<uint32_t> attachable::handle_exception(const std::exception_ptr&) {
return none;
}
......
......@@ -328,7 +328,7 @@ response_promise fetch_response_promise(local_actor*, response_promise& hdl) {
// enables `return sync_send(...).then(...)`
bool handle_message_id_res(local_actor* self, message& res,
optional<response_promise> hdl) {
maybe<response_promise> hdl) {
if (res.match_elements<atom_value, uint64_t>()
&& res.get_as<atom_value>(0) == atom("MESSAGE_ID")) {
CAF_LOGF_DEBUG("message handler returned a message id wrapper");
......@@ -360,9 +360,9 @@ bool handle_message_id_res(local_actor* self, message& res,
// - extracts response message from handler
// - returns true if fun was successfully invoked
template <class Handle = int>
optional<message> post_process_invoke_res(local_actor* self,
maybe<message> post_process_invoke_res(local_actor* self,
message_id mid,
optional<message>&& res,
maybe<message>&& res,
Handle hdl = Handle{}) {
CAF_LOGF_TRACE(CAF_MARG(mid, integer_value) << ", " << CAF_TSARG(res));
if (! res) {
......@@ -523,7 +523,7 @@ bool local_actor::awaits(message_id mid) const {
predicate);
}
optional<local_actor::pending_response&>
maybe<local_actor::pending_response&>
local_actor::find_pending_response(message_id mid) {
pending_response_predicate predicate{mid};
auto last = pending_responses_.end();
......
......@@ -143,7 +143,7 @@ message message::slice(size_t pos, size_t n) const {
return message{detail::decorated_tuple::make(vals_, std::move(mapping))};
}
optional<message> message::apply(message_handler handler) {
maybe<message> message::apply(message_handler handler) {
return handler(*this);
}
......@@ -262,7 +262,7 @@ message::cli_res message::extract_opts(std::vector<cli_arg> xs,
// store any occurred error in a temporary variable returned at the end
std::string error;
auto res = extract({
[&](const std::string& arg) -> optional<skip_message_t> {
[&](const std::string& arg) -> maybe<skip_message_t> {
if (arg.empty() || arg.front() != '-') {
return skip_message();
}
......@@ -307,7 +307,7 @@ message::cli_res message::extract_opts(std::vector<cli_arg> xs,
return skip_message();
},
[&](const std::string& arg1,
const std::string& arg2) -> optional<skip_message_t> {
const std::string& arg2) -> maybe<skip_message_t> {
if (arg1.size() < 2 || arg1[0] != '-' || arg1[1] == '-') {
return skip_message();
}
......@@ -341,8 +341,8 @@ message::cli_arg::cli_arg(std::string nstr, std::string tstr)
}
message::cli_arg::cli_arg(std::string nstr, std::string tstr, consumer f)
: name(std::move(name)),
text(std::move(text)),
: name(std::move(nstr)),
text(std::move(tstr)),
fun(std::move(f)) {
// nop
}
......
......@@ -160,7 +160,7 @@ message message_builder::move_to_message() {
return result;
}
optional<message> message_builder::apply(message_handler handler) {
maybe<message> message_builder::apply(message_handler handler) {
// avoid detaching of data_ by moving the data to a message object,
// calling message::apply and moving the data back
message::data_ptr ptr;
......
......@@ -44,7 +44,7 @@ public:
};
void parse_config(std::istream& input, config_format format,
optional<std::ostream&> errors) {
maybe<std::ostream&> errors) {
if (! input)
return;
auto cs = experimental::whereis(atom("ConfigServ"));
......@@ -59,8 +59,8 @@ void parse_config(std::istream& input, config_format format,
}
void parse_config(const std::string& file_name,
optional<config_format> format,
optional<std::ostream&> errors) {
maybe<config_format> format,
maybe<std::ostream&> errors) {
if (! format) {
// try to detect file format according to file extension
if (file_name.size() < 5)
......
......@@ -28,7 +28,7 @@ namespace caf {
void detail::parse_ini(std::istream& input,
config_consumer consumer,
optional<std::ostream&> errors) {
maybe<std::ostream&> errors) {
std::string group;
std::string line;
size_t ln = 0; // line number
......
......@@ -30,7 +30,7 @@ class exception_testee : public event_based_actor {
public:
~exception_testee();
exception_testee() {
set_exception_handler([](const std::exception_ptr&) -> optional<uint32_t> {
set_exception_handler([](const std::exception_ptr&) -> maybe<uint32_t> {
return exit_reason::user_defined + 2;
});
}
......@@ -49,7 +49,7 @@ exception_testee::~exception_testee() {
CAF_TEST(test_custom_exception_handler) {
auto handler = [](const std::exception_ptr& eptr) -> optional<uint32_t> {
auto handler = [](const std::exception_ptr& eptr) -> maybe<uint32_t> {
try {
std::rethrow_exception(eptr);
}
......
......@@ -771,7 +771,7 @@ namespace {
class exception_testee : public event_based_actor {
public:
exception_testee() {
set_exception_handler([](const std::exception_ptr&) -> optional<uint32_t> {
set_exception_handler([](const std::exception_ptr&) -> maybe<uint32_t> {
return exit_reason::user_defined + 2;
});
}
......@@ -787,7 +787,7 @@ public:
} // namespace <anonymous>
CAF_TEST(custom_exception_handler) {
auto handler = [](const std::exception_ptr& eptr) -> optional<uint32_t> {
auto handler = [](const std::exception_ptr& eptr) -> maybe<uint32_t> {
try {
std::rethrow_exception(eptr);
}
......
......@@ -46,7 +46,7 @@ CAF_TEST(simple_ints) {
auto one = on(1) >> [] { };
auto two = on(2) >> [] { };
auto three = on(3) >> [] { };
auto skip_two = [](int i) -> optional<skip_message_t> {
auto skip_two = [](int i) -> maybe<skip_message_t> {
if (i == 2) {
return skip_message();
}
......
......@@ -39,8 +39,8 @@ using namespace std;
using hi_atom = atom_constant<atom("hi")>;
using ho_atom = atom_constant<atom("ho")>;
function<optional<string>(const string&)> starts_with(const string& s) {
return [=](const string& str) -> optional<string> {
function<maybe<string>(const string&)> starts_with(const string& s) {
return [=](const string& str) -> maybe<string> {
if (str.size() > s.size() && str.compare(0, s.size(), s) == 0) {
auto res = str.substr(s.size());
return res;
......@@ -49,7 +49,7 @@ function<optional<string>(const string&)> starts_with(const string& s) {
};
}
optional<int> toint(const string& str) {
maybe<int> toint(const string& str) {
char* endptr = nullptr;
int result = static_cast<int>(strtol(str.c_str(), &endptr, 10));
if (endptr != nullptr && *endptr == '\0') {
......@@ -128,7 +128,7 @@ CAF_TEST(atom_constants) {
CAF_TEST(guards_called) {
bool guard_called = false;
auto guard = [&](int arg) -> optional<int> {
auto guard = [&](int arg) -> maybe<int> {
guard_called = true;
return arg;
};
......
......@@ -19,67 +19,64 @@
#include "caf/config.hpp"
#define CAF_SUITE optional
#define CAF_SUITE maybe
#include "caf/test/unit_test.hpp"
#include <string>
#include "caf/optional.hpp"
#include "caf/maybe.hpp"
using namespace std;
using namespace caf;
namespace {
struct qwertz {
qwertz(int i, int j) : i_(i), j_(j) {
// nop
}
int i_;
int j_;
};
bool operator==(const qwertz& lhs, const qwertz& rhs) {
return lhs.i_ == rhs.i_ && lhs.j_ == rhs.j_;
}
} // namespace <anonymous>
CAF_TEST(empties) {
optional<int> i;
optional<int> j;
maybe<int> i;
maybe<int> j;
CAF_CHECK(i == j);
CAF_CHECK(!(i != j));
}
CAF_TEST(unequal) {
optional<int> i = 5;
optional<int> j = 6;
maybe<int> i = 5;
maybe<int> j = 6;
CAF_CHECK(!(i == j));
CAF_CHECK(i != j);
}
CAF_TEST(distinct_types) {
optional<int> i;
optional<double> j;
maybe<int> i;
maybe<double> j;
CAF_CHECK(i == j);
CAF_CHECK(!(i != j));
}
struct qwertz {
qwertz(int i, int j) : i_(i), j_(j) {
// nop
}
int i_;
int j_;
};
inline bool operator==(const qwertz& lhs, const qwertz& rhs) {
return lhs.i_ == rhs.i_ && lhs.j_ == rhs.j_;
}
CAF_TEST(custom_type_none) {
optional<qwertz> i;
maybe<qwertz> i;
CAF_CHECK(i == none);
}
CAF_TEST(custom_type_engaged) {
qwertz obj{1, 2};
optional<qwertz> j = obj;
maybe<qwertz> j = obj;
CAF_CHECK(j != none);
CAF_CHECK(obj == j);
CAF_CHECK(j == obj );
CAF_CHECK(obj == *j);
CAF_CHECK(*j == obj);
}
CAF_TEST(test_optional) {
optional<qwertz> i = qwertz(1,2);
CAF_CHECK(! i.empty());
optional<qwertz> j = { { 1, 2 } };
CAF_CHECK(! j.empty());
}
......@@ -365,7 +365,7 @@ CAF_TEST(sync_send) {
[](error_atom) {
CAF_TEST_ERROR("A didn't receive sync response");
},
[&](const down_msg& dm) -> optional<skip_message_t> {
[&](const down_msg& dm) -> maybe<skip_message_t> {
if (dm.reason == exit_reason::normal) {
return skip_message();
}
......
......@@ -173,7 +173,7 @@ public:
uint16_t local_port(accept_handle hdl);
/// Returns the handle associated to given local `port` or `none`.
optional<accept_handle> hdl_by_port(uint16_t port);
maybe<accept_handle> hdl_by_port(uint16_t port);
/// Closes all connections and acceptors.
void close_all();
......
......@@ -299,7 +299,7 @@ public:
using erase_callback = callback<const node_id&>;
/// Returns a route to `target` or `none` on error.
optional<route> lookup(const node_id& target);
maybe<route> lookup(const node_id& target);
/// Returns the ID of the peer connected via `hdl` or
/// `invalid_node_id` if `hdl` is unknown.
......@@ -446,7 +446,7 @@ public:
void handle_node_shutdown(const node_id& affected_node);
/// Returns a route to `target` or `none` on error.
optional<routing_table::route> lookup(const node_id& target);
maybe<routing_table::route> lookup(const node_id& target);
/// Flushes the underlying buffer of `path`.
void flush(const routing_table::route& path);
......@@ -517,7 +517,7 @@ public:
/// actor published at `port` to `buf`. If `port == none` or
/// if no actor is published at this port then a standard handshake is
/// written (e.g. used when establishing direct connections on-the-fly).
void write_server_handshake(buffer_type& buf, optional<uint16_t> port);
void write_server_handshake(buffer_type& buf, maybe<uint16_t> port);
/// Writes the client handshake to `buf`.
void write_client_handshake(buffer_type& buf, const node_id& remote_side);
......
......@@ -82,7 +82,7 @@ struct basp_broker_state : actor_namespace::backend, basp::instance::callee {
connection_handle hdl;
node_id id;
uint16_t remote_port;
optional<response_promise> callback;
maybe<response_promise> callback;
};
void set_context(connection_handle hdl);
......
......@@ -693,7 +693,7 @@ private:
};
native_socket new_tcp_connection_impl(const std::string&, uint16_t,
optional<protocol> preferred = none);
maybe<protocol> preferred = none);
default_socket new_tcp_connection(const std::string& host, uint16_t port);
......
......@@ -27,7 +27,7 @@
#include <functional>
#include <initializer_list>
#include "caf/optional.hpp"
#include "caf/maybe.hpp"
#include "caf/io/network/protocol.hpp"
......@@ -70,8 +70,8 @@ public:
bool include_localhost = true);
/// Returns a native IPv4 or IPv6 translation of `host`.
static optional<std::pair<std::string, protocol>>
native_address(const std::string& host, optional<protocol> preferred = none);
static maybe<std::pair<std::string, protocol>>
native_address(const std::string& host, maybe<protocol> preferred = none);
};
} // namespace network
......
......@@ -207,7 +207,7 @@ uint16_t abstract_broker::local_port(accept_handle hdl) {
return i != doormen_.end() ? i->second->port() : 0;
}
optional<accept_handle> abstract_broker::hdl_by_port(uint16_t port) {
maybe<accept_handle> abstract_broker::hdl_by_port(uint16_t port) {
for (auto& kvp : doormen_)
if (kvp.second->port() == port)
return kvp.first;
......
......@@ -185,7 +185,7 @@ routing_table::~routing_table() {
// nop
}
optional<routing_table::route> routing_table::lookup(const node_id& target) {
maybe<routing_table::route> routing_table::lookup(const node_id& target) {
auto hdl = lookup_direct(target);
if (hdl != invalid_connection_handle)
return route{parent_->wr_buf(hdl), target, hdl};
......@@ -502,7 +502,7 @@ void instance::handle_node_shutdown(const node_id& affected_node) {
tbl_.erase(affected_node, cb);
}
optional<routing_table::route> instance::lookup(const node_id& target) {
maybe<routing_table::route> instance::lookup(const node_id& target) {
return tbl_.lookup(target);
}
......@@ -635,7 +635,7 @@ void instance::write(buffer_type& buf, header& hdr, payload_writer* pw) {
}
void instance::write_server_handshake(buffer_type& out_buf,
optional<uint16_t> port) {
maybe<uint16_t> port) {
using namespace detail;
published_actor* pa = nullptr;
if (port) {
......
......@@ -479,7 +479,7 @@ behavior basp_broker::make_behavior() {
// received from some system calls like whereis
[=](forward_atom, const actor_addr& sender,
const node_id& receiving_node, atom_value receiver_name,
const message& msg) -> optional<message> {
const message& msg) -> maybe<message> {
CAF_LOG_TRACE(CAF_TSARG(sender)
<< ", " << CAF_TSARG(receiving_node)
<< ", " << CAF_TSARG(receiver_name)
......
......@@ -20,7 +20,7 @@
#include "caf/io/network/default_multiplexer.hpp"
#include "caf/config.hpp"
#include "caf/optional.hpp"
#include "caf/maybe.hpp"
#include "caf/exception.hpp"
#include "caf/make_counted.hpp"
......@@ -1094,7 +1094,7 @@ bool ip_connect(native_socket fd, const std::string& host, uint16_t port) {
}
native_socket new_tcp_connection_impl(const std::string& host, uint16_t port,
optional<protocol> preferred) {
maybe<protocol> preferred) {
CAF_LOGF_TRACE(CAF_ARG(host) << ", " << CAF_ARG(port)
<< ", " << CAF_TSARG(preferred));
CAF_LOGF_INFO("try to connect to " << host << " on port " << port);
......
......@@ -216,9 +216,9 @@ std::vector<std::string> interfaces::list_addresses(protocol proc,
return list_addresses({proc}, include_localhost);
}
optional<std::pair<std::string, protocol>>
maybe<std::pair<std::string, protocol>>
interfaces::native_address(const std::string& host,
optional<protocol> preferred) {
maybe<protocol> preferred) {
addrinfo hint;
memset(&hint, 0, sizeof(hint));
hint.ai_socktype = SOCK_STREAM;
......
......@@ -270,7 +270,7 @@ public:
}
void connect_node(size_t i,
optional<accept_handle> ax = none,
maybe<accept_handle> ax = none,
actor_id published_actor_id = invalid_actor_id,
set<string> published_actor_ifs = std::set<std::string>{}) {
auto src = ax ? *ax : ahdl_;
......
......@@ -246,7 +246,7 @@ void spawn5_client(event_based_actor* self) {
template <class F>
void await_down(event_based_actor* self, actor ptr, F continuation) {
self->become(
[=](const down_msg& dm) -> optional<skip_message_t> {
[=](const down_msg& dm) -> maybe<skip_message_t> {
if (dm.source == ptr) {
continuation();
return none;
......
Subproject commit 200eb3f43fb243515d0652324e6d606dede3f676
Subproject commit 5feadf0676e48d57b14dcfc76a27d8265434ca01
Subproject commit 83de14803c841a7113c4b13c94624a55f3eec984
Subproject commit 70ab7b5fcd3b27ae8ee23ebffb87186ef8bc4776
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