Skip to content

Instantly share code, notes, and snippets.

@loliGothicK
Last active May 24, 2018 20:52
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 loliGothicK/bf5b2013fcf51bd92b99349000b6a73c to your computer and use it in GitHub Desktop.
Save loliGothicK/bf5b2013fcf51bd92b99349000b6a73c to your computer and use it in GitHub Desktop.
shared_ptr<T[]>, shared_ptr<T[N]>のレンジ
#include <iostream>
#include "shared_range.hpp"
int main()
{
using cranberries::shared_util::shared_range;
auto ln = []{ std::cout << std::endl; };
std::shared_ptr<int[]> p1 { new int[10]{1,2,3,4,5,6,7,8,9,10} };
// [0, 5)
shared_range{0, 5}(std::as_const(p1),[](auto item){
std::cout << item << " ";
});
ln();
std::shared_ptr<int[10]> p2 { new int[10]{1,2,3,4,5,6,7,8,9,10} };
// for_each
shared_range::for_each(std::as_const(p2),[](auto item){
std::cout << item << " ";
});
ln();
// left folding
std::cout << shared_range::foldl(p2, [](auto a, auto b){ return a+b; }) << std::endl;
}
#pragma once
#include <memory>
#include <utility>
#include <type_traits>
namespace cranberries::fold_hack {
template < class ResultType, class F >
class fold_collect_t {
ResultType result;
F f;
public:
template < class F_ >
constexpr fold_collect_t(ResultType init, F_&& f): result{init}, f{ std::forward<F_>(f) } {}
fold_collect_t& operator + (const ResultType& x){
result = f(result, x);
return *this;
}
ResultType get() const { return result; }
};
template < class ResultType, class F > fold_collect_t(ResultType, F&&) -> fold_collect_t<ResultType,F>;
}
namespace cranberries::shared_util{
class shared_range {
size_t first, upper_bound;
template < class T, class F, size_t N, size_t Discard, size_t... Indices >
static auto foldl_invoker(std::shared_ptr<T[N]>const & p, F&& f, std::index_sequence<Discard, Indices...>){
return ( fold_hack::fold_collect_t{ p[0], std::forward<F>(f) } + ... + p[Indices] ).get();
}
template < class T, class F, size_t N, size_t... Indices >
static auto foldr_invoker(std::shared_ptr<T[N]>const & p, F&& f, std::index_sequence<Indices...>){
return ( p[Indices] + ... + fold_hack::fold_collect_t{ p[N-1], std::forward<F>(f) } ).get();
}
public:
shared_range(size_t first, size_t last): first{first}, upper_bound{last} {}
template < class F, class T, size_t N >
void operator()(std::shared_ptr<T[N]>const & p, F&& f){
if(p) for(size_t i{first}; i < upper_bound; ++i) f( p[i] );
}
template < class F, class T >
void operator()(std::shared_ptr<T[]> const& p, F&& f){
if(p) for(size_t i{first}; i < upper_bound; ++i) f( p[i] );
}
template < class F, class T, size_t N >
static void for_each(std::shared_ptr<T[N]>const & p, F&& f){
if(p) for(size_t i{}; i < N; ++i) f( p[i] );
}
template < class F, class T, size_t N >
static auto foldl(std::shared_ptr<T[N]>const & p, F&& f){
return foldl_invoker(p, std::forward<F>(f), std::make_index_sequence<N>{});
}
template < class F, class T, size_t N >
static auto foldr(std::shared_ptr<T[N]>const & p, F&& f){
return foldr_invoker(p, std::forward<F>(f), std::make_index_sequence<N-1>{});
}
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment