Skip to content

Instantly share code, notes, and snippets.

@schaumb
Last active July 23, 2020 16:57
Show Gist options
  • Save schaumb/15401195578654c10bc453b22b72e1c3 to your computer and use it in GitHub Desktop.
Save schaumb/15401195578654c10bc453b22b72e1c3 to your computer and use it in GitHub Desktop.
Create a function returnable range collection.
#include <boost/utility/base_from_member.hpp>
#include <boost/range/any_range.hpp>
#include <boost/iterator/iterator_traits.hpp>
#include <any>
#include <type_traits>
template<typename T, typename Traversal = boost::forward_traversal_tag>
struct collection : boost::base_from_member<std::any>,
boost::base_from_member<std::function<boost::any_range<T, Traversal>(std::any&)>>,
boost::any_range<T, Traversal> {
using AnyBase = boost::base_from_member<std::any>;
using RangeMakerBase = boost::base_from_member<std::function<boost::any_range<T, Traversal>(std::any&)>>;
using RangeBase = boost::any_range<T, Traversal>;
collection() = default;
template<typename Collection>
collection(Collection&& c) :
AnyBase{std::forward<Collection>(c)},
RangeMakerBase{[](std::any& any) -> boost::any_range<T, Traversal> {
return {*std::any_cast<std::remove_reference_t<Collection>>(std::addressof(any))}; }},
RangeBase{this->RangeMakerBase::member(this->AnyBase::member)}
{}
template<typename Collection>
collection& operator=(Collection&& c) {
this->AnyBase::member.emplace<Collection>(std::forward<Collection>(c));
this->RangeMakerBase::member = [] (std::any& any) -> boost::any_range<T, Traversal> { return {*std::any_cast<std::remove_reference_t<Collection>>(std::addressof(any))}; };
this->assign(this->RangeMakerBase::member(this->AnyBase::member));
return *this;
}
collection(collection&& oth) :
AnyBase{std::move(oth.AnyBase::member)},
RangeMakerBase{std::move(oth.RangeMakerBase::member)},
RangeBase{this->RangeMakerBase::member(this->AnyBase::member)}
{}
collection& operator=(collection&& oth) {
this->AnyBase::member = std::move(oth.AnyBase::member);
this->RangeMakerBase::member = std::move(oth.RangeMakerBase::member);
this->assign(this->RangeMakerBase::member(this->AnyBase::member));
return *this;
}
collection(const collection& oth) = delete;
collection& operator=(const collection& oth) = delete;
};
template<typename Collection>
collection(Collection&& c) -> collection<typename boost::iterator_value<decltype(boost::begin(std::declval<Collection&>()))>::type>;
template<typename Traversal = void, typename Collection>
collection<typename boost::iterator_value<decltype(boost::begin(std::declval<Collection&>()))>::type,
std::conditional_t<std::is_void_v<Traversal>,
typename boost::iterator_traversal<decltype(boost::begin(std::declval<Collection&>()))>::type, Traversal>>
make_collection(Collection&& c) {
return {std::forward<Collection>(c)};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment