// -*- mode:C++; tab-width:8; c-basic-offset:4; indent-tabs-mode:t -*-
// vim: ts=8 sw=4 smarttab
-/*
- * Copied from:
- * https://github.com/exclipy/inline_variant_visitor/blob/master/inline_variant.hpp
- */
#ifndef INLINE_VARIANT_H
#define INLINE_VARIANT_H
-#include <boost/function_types/function_arity.hpp>
-#include <boost/fusion/algorithm/transformation/transform.hpp>
-#include <boost/mpl/contains.hpp>
-#include <boost/mpl/map.hpp>
-#include <boost/mpl/vector.hpp>
-#include <boost/mpl/range_c.hpp>
-#include <boost/noncopyable.hpp>
+#include <utility>
+#include <variant>
-#include "function_signature.h"
-
-namespace detail {
-
-// A metafunction class for getting the argument type from a unary function or functor type
-struct function_arg_extractor
-{
- // Function is either a function type like void(int const&), or a functor - eg. a class with void operator(int)
- // Sets type to the argument type with the constness and referenceness stripped (eg. int)
- template <typename Function>
- struct apply
- {
- private:
- typedef typename boost::remove_const< typename boost::remove_reference<Function>::type >::type bare_type;
- typedef typename signature_of<bare_type>::type normalized_function_type;
- typedef typename boost::function_types::function_arity<normalized_function_type>::type arity;
- typedef typename boost::function_types::parameter_types<normalized_function_type>::type parameter_types;
- typedef typename boost::function_types::result_type<normalized_function_type>::type result_type;
-
- BOOST_STATIC_ASSERT_MSG((arity::value == 1), "make_visitor called with a non-unary function");
-
- typedef typename boost::mpl::front<parameter_types>::type parameter_type;
- public:
- typedef typename boost::remove_const< typename boost::remove_reference<parameter_type>::type >::type type;
- };
-};
-
-struct make_pair
-{
- template <typename AType, typename Ind>
- struct apply {
- typedef boost::mpl::pair<AType, Ind> type;
- };
-};
-
-// A metafunction class that asserts the second argument is in Allowed, and returns void
-template<typename Allowed>
-struct check_in
-{
- template <typename Type1, typename Type2>
- struct apply
- {
- private:
- BOOST_STATIC_ASSERT_MSG((boost::mpl::contains<Allowed, typename boost::mpl::first<Type2>::type>::value),
- "make_visitor called with spurious handler functions");
- public:
- typedef void type;
- };
-};
-
-template <typename Seq>
-struct as_map
-{
-private:
- struct insert_helper {
- template <typename M, typename P>
- struct apply
- {
- typedef typename boost::mpl::insert<
- M,
- P>::type type;
- };
- };
-public:
- typedef typename boost::mpl::fold<Seq, boost::mpl::map0<>, insert_helper>::type type;
-};
-
-// A functor template suitable for passing into apply_visitor. The constructor accepts the list of handler functions,
-// which are then exposed through a set of operator()s
-template <typename Result, typename Variant, typename... Functions>
-struct generic_visitor : boost::static_visitor<Result>, boost::noncopyable
-{
-private:
- typedef generic_visitor<Result, Variant, Functions...> type;
-
- // Compute the function_map type
- typedef boost::mpl::vector<Functions...> function_types;
- typedef typename boost::mpl::transform<function_types, function_arg_extractor>::type arg_types;
- typedef typename boost::mpl::transform<
- arg_types,
- boost::mpl::range_c<int, 0, boost::mpl::size<arg_types>::value>,
- make_pair
- >::type pair_list;
- typedef typename as_map<pair_list>::type fmap;
-
- // Check that the argument types are unique
- BOOST_STATIC_ASSERT_MSG((boost::mpl::size<fmap>::value == boost::mpl::size<arg_types>::value),
- "make_visitor called with non-unique argument types for handler functions");
-
- // Check that there aren't any argument types not in the variant types
- typedef typename boost::mpl::fold<fmap, void, check_in<typename Variant::types> >::type dummy;
-
- boost::fusion::vector<Functions...> fvec;
-
-
- template <typename T>
- Result apply_helper(const T& object, boost::mpl::true_) const {
- typedef typename boost::mpl::at<fmap, T>::type Ind;
- return boost::fusion::at<Ind>(fvec)(object);
- }
-
- template <typename T>
- Result apply_helper(const T& object, boost::mpl::false_) const {
- return Result();
- }
-
- BOOST_MOVABLE_BUT_NOT_COPYABLE(generic_visitor)
-
-public:
- generic_visitor(BOOST_RV_REF(type) other)
- :
- fvec(boost::move(other.fvec))
- {
- }
- generic_visitor(Functions&&... functions)
- :
- fvec(std::forward<Functions>(functions)...)
- {
- }
-
- template <typename T>
- Result operator()(const T& object) const {
- typedef typename boost::mpl::has_key<fmap, T>::type correct_key;
- BOOST_STATIC_ASSERT_MSG(correct_key::value,
- "make_visitor called without specifying handlers for all required types");
- return apply_helper(object, correct_key());
- }
-};
-
-// A metafunction class for getting the return type of a function
-struct function_return_extractor
-{
- template <typename Function>
- struct apply : boost::function_types::result_type<typename signature_of<Function>::type>
- {
- };
-};
-
-// A metafunction class that asserts the two arguments are the same and returns the first one
-struct check_same
-{
- template <typename Type1, typename Type2>
- struct apply
- {
- private:
- BOOST_STATIC_ASSERT_MSG((boost::is_same<Type1, Type2>::value),
- "make_visitor called with functions of differing return types");
- public:
- typedef Type1 type;
- };
-};
-
-// A metafunction for getting the required generic_visitor type for the set of Functions
-template <typename Variant, typename... Functions>
-struct get_generic_visitor
-{
-private:
- typedef boost::mpl::vector<Functions...> function_types;
- typedef typename boost::mpl::transform<
- function_types,
- boost::remove_const< boost::remove_reference<boost::mpl::_1> >
- >::type bare_function_types;
- typedef typename boost::mpl::transform<bare_function_types, function_return_extractor>::type return_types;
-
-public:
- // Set result_type to the return type of the first function
- typedef typename boost::mpl::front<return_types>::type result_type;
- typedef generic_visitor<result_type, Variant, Functions...> type;
-
-private:
- // Assert that every return type is the same as the first one
- typedef typename boost::mpl::fold<return_types, result_type, check_same>::type dummy;
-};
-
-// Accepts a set of functions and returns an object suitable for apply_visitor
-template <typename Variant, typename... Functions>
-auto make_visitor(BOOST_RV_REF(Functions)... functions)
- -> typename detail::get_generic_visitor<Variant, Functions...>::type
-{
- return typename detail::get_generic_visitor<Variant, Functions...>::type(boost::forward<Functions>(functions)...);
-}
-
-}
+template <class... Functions>
+struct overloaded : Functions... { using Functions::operator()...; };
template <typename Variant, typename... Functions>
-auto match(Variant const& variant, BOOST_RV_REF(Functions)... functions)
- -> typename detail::get_generic_visitor<Variant, Functions...>::result_type
+auto match(Variant const& variant, Functions... functions)
{
- return boost::apply_visitor(detail::make_visitor<Variant>(
- boost::forward<Functions>(functions)...), variant);
+ return std::visit(overloaded{std::forward<Functions>(functions)...}, variant);
}
#endif
#include <map>
#include <memory>
#include <optional>
+#include <variant>
#include "common/hobject.h"
#ifndef WITH_CRIMSON
hobject_t source; // must be temp object
};
};
- using InitType = boost::variant<
+ using InitType = std::variant<
Init::None,
Init::Create,
Init::Clone,
return delete_first;
}
bool is_delete() const {
- return boost::get<Init::None>(&init_type) != nullptr && delete_first;
+ return std::holds_alternative<Init::None>(init_type) && delete_first;
}
bool is_none() const {
- return boost::get<Init::None>(&init_type) != nullptr && !delete_first;
+ return std::holds_alternative<Init::None>(init_type) && !delete_first;
}
bool is_fresh_object() const {
- return boost::get<Init::None>(&init_type) == nullptr;
+ return !std::holds_alternative<Init::None>(init_type);
}
bool is_rename() const {
- return boost::get<Init::Rename>(&init_type) != nullptr;
+ return std::holds_alternative<Init::Rename>(init_type);
}
bool has_source(hobject_t *source = nullptr) const {
return match(
uint64_t len;
};
};
- using BufferUpdateType = boost::variant<
+ using BufferUpdateType = std::variant<
BufferUpdate::Write,
BufferUpdate::Zero,
BufferUpdate::CloneRange>;
return match(
left,
[&](const BufferUpdate::Write &w) -> bool {
- auto r = boost::get<BufferUpdate::Write>(&right);
+ auto r = std::get_if<BufferUpdate::Write>(&right);
return r != nullptr && (w.fadvise_flags == r->fadvise_flags);
},
[&](const BufferUpdate::Zero &) -> bool {
- auto r = boost::get<BufferUpdate::Zero>(&right);
- return r != nullptr;
+ return std::holds_alternative<BufferUpdate::Zero>(right);
},
[&](const BufferUpdate::CloneRange &c) -> bool {
return false;
return match(
left,
[&](const BufferUpdate::Write &w) -> BufferUpdateType {
- auto r = boost::get<BufferUpdate::Write>(&right);
+ auto r = std::get_if<BufferUpdate::Write>(&right);
ceph_assert(r && w.fadvise_flags == r->fadvise_flags);
ceph::buffer::list bl = w.buffer;
bl.append(r->buffer);
return BufferUpdate::Write{bl, w.fadvise_flags};
},
[&](const BufferUpdate::Zero &z) -> BufferUpdateType {
- auto r = boost::get<BufferUpdate::Zero>(&right);
- ceph_assert(r);
+ auto r = std::get_if<BufferUpdate::Zero>(&right);
+ ceph_assert(r != nullptr);
return BufferUpdate::Zero{z.len + r->len};
},
[&](const BufferUpdate::CloneRange &c) -> BufferUpdateType {
[&](const pair<const hobject_t, PGTransaction::ObjectOperation> &p) {
ASSERT_EQ(p.first, h);
using T = PGTransaction::ObjectOperation::Init;
- ASSERT_TRUE(boost::get<T::None>(&p.second.init_type));
+ ASSERT_TRUE(std::holds_alternative<T::None>(p.second.init_type));
++num;
});
ASSERT_EQ(num, 1u);
using T = PGTransaction::ObjectOperation::Init;
if (num == 0) {
ASSERT_EQ(p.first, h);
- ASSERT_TRUE(boost::get<T::Clone>(&p.second.init_type));
+ ASSERT_TRUE(std::holds_alternative<T::Clone>(p.second.init_type));
ASSERT_EQ(
- boost::get<T::Clone>(&p.second.init_type)->source,
+ std::get_if<T::Clone>(&p.second.init_type)->source,
h2);
} else if (num == 1) {
ASSERT_EQ(p.first, h2);
- ASSERT_TRUE(boost::get<T::None>(&p.second.init_type));
+ ASSERT_TRUE(std::holds_alternative<T::None>(p.second.init_type));
} else {
ASSERT_LT(num, 2u);
}
using T = PGTransaction::ObjectOperation::Init;
if (num == 0) {
ASSERT_EQ(p.first, h);
- ASSERT_TRUE(boost::get<T::Clone>(&p.second.init_type));
+ ASSERT_TRUE(std::holds_alternative<T::Clone>(p.second.init_type));
ASSERT_EQ(
- boost::get<T::Clone>(&p.second.init_type)->source,
+ std::get_if<T::Clone>(&p.second.init_type)->source,
h2);
} else if (num == 1) {
ASSERT_EQ(p.first, h2);
- ASSERT_TRUE(boost::get<T::Clone>(&p.second.init_type));
+ ASSERT_TRUE(std::holds_alternative<T::Clone>(p.second.init_type));
ASSERT_EQ(
- boost::get<T::Clone>(&p.second.init_type)->source,
+ std::get_if<T::Clone>(&p.second.init_type)->source,
h3);
} else if (num == 2) {
ASSERT_EQ(p.first, h3);
- ASSERT_TRUE(boost::get<T::None>(&p.second.init_type));
+ ASSERT_TRUE(std::holds_alternative<T::None>(p.second.init_type));
} else {
ASSERT_LT(num, 3u);
}
if (p.first == h) {
ASSERT_TRUE(p.second.is_delete());
} else if (p.first == h2) {
- ASSERT_TRUE(boost::get<T::Clone>(&p.second.init_type));
+ ASSERT_TRUE(std::holds_alternative<T::Clone>(p.second.init_type));
ASSERT_EQ(
- boost::get<T::Clone>(&p.second.init_type)->source,
+ std::get_if<T::Clone>(&p.second.init_type)->source,
h3);
}
ASSERT_LT(num, 2u);