Skip to content

Instantly share code, notes, and snippets.

@hikarin522
Last active April 2, 2020 03:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hikarin522/31bcdb5cd3437554f6f3f6380c35ac75 to your computer and use it in GitHub Desktop.
Save hikarin522/31bcdb5cd3437554f6f3f6380c35ac75 to your computer and use it in GitHub Desktop.
#pragma once
#include <boost/version.hpp>
#if BOOST_VERSION >= 105900
#define ENABLE_RANKED_INDEX
#endif
#include <boost/multi_index/member.hpp>
#include <boost/multi_index/mem_fun.hpp>
#include <boost/multi_index/global_fun.hpp>
#include <boost/multi_index/tag.hpp>
#include <boost/multi_index/ordered_index_fwd.hpp>
#include <boost/multi_index/hashed_index_fwd.hpp>
#ifdef ENABLE_RANKED_INDEX
#include <boost/multi_index/ranked_index_fwd.hpp>
#endif
namespace boost_multi_index_utils {
#ifdef __cpp_template_auto
template <auto ptr, class ...Tags>
#else
template <class P, P ptr, class ...Tags>
#endif
class idx {
template <class C, class T>
static auto get_type(T C::*)
-> boost::multi_index::member<C, T, ptr>;
template <class C, class T>
static auto get_type(T (C::*)())
-> boost::multi_index::mem_fun<C, T, ptr>;
template <class C, class T>
static auto get_type(T (C::*)() const)
-> boost::multi_index::const_mem_fun<C, T, ptr>;
template <class C, class T>
static auto get_type(T (*)(C))
-> boost::multi_index::global_fun<C, T, ptr>;
public:
using key = decltype(get_type(ptr));
#ifdef __cpp_template_auto
using tag = boost::multi_index::tag<idx<ptr>, Tags...>
#else
using tag = boost::multi_index::tag<idx<P, ptr>, Tags...>;
#endif
template <class Pred = boost::mpl::na>
using ordered_unique = boost::multi_index::ordered_unique<tag, key, Pred>;
template <class Pred = boost::mpl::na>
using ordered_non_unique = boost::multi_index::ordered_non_unique<tag, key, Pred>;
template <class Hash = boost::mpl::na, class Pred = boost::mpl::na>
using hashed_unique = boost::multi_index::hashed_unique<tag, key, Hash, Pred>;
template <class Hash = boost::mpl::na, class Pred = boost::mpl::na>
using hashed_non_unique = boost::multi_index::hashed_non_unique<tag, key, Hash, Pred>;
#ifdef ENABLE_RANKED_INDEX
template <class Compare = boost::mpl::na>
using ranked_unique = boost::multi_index::ranked_unique<tag, key, Compare>;
template <class Compare = boost::mpl::na>
using ranked_non_unique = boost::multi_index::ranked_non_unique<tag, key, Compare>;
#endif
};
} // namespace boost_multi_index_utils
#define IDX(...) _IDX(__VA_ARGS__)
#ifdef __cpp_template_auto
#define _IDX(ptr, ...) ::boost_multi_index_utils::idx<ptr, ##__VA_ARGS__>
#else
#define _IDX(ptr, ...) ::boost_multi_index_utils::idx<decltype(ptr), ptr, ##__VA_ARGS__>
#endif
// C++20 統一コンテナ削除
#include <boost/multi_index/sequenced_index_fwd.hpp>
#include <boost/multi_index/random_access_index_fwd.hpp>
// https://gist.github.com/hikarin522/68660a830c44697075739cd195f3f87c
#include "erase_if.hpp"
namespace std_erase_detail {
template <class ...T>
struct is_list<boost::multi_index::detail::sequenced_index<T...>>: std::true_type { };
template <class ...T>
struct is_list<boost::multi_index::detail::random_access_index<T...>>: std::true_type { };
template <class ...T>
struct is_map<boost::multi_index::detail::ordered_index<T...>>: std::true_type { };
template <class ...T>
struct is_map<boost::multi_index::detail::hashed_index<T...>>: std::true_type { };
#ifdef ENABLE_RANKED_INDEX
template <class ...T>
struct is_map<boost::multi_index::detail::ranked_index<T...>>: std::true_type { };
#endif
} // namespace std_erase_detail
namespace std {
template <class ...T, class Pred>
auto erase_if(boost::multi_index::container<T...> &c, const Pred &pred) {
return std::erase_if(c.get<0>(), pred);
}
} // namespace std
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment