Skip to content

Instantly share code, notes, and snippets.

@tyanmahou
Last active October 31, 2017 09:09
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 tyanmahou/45341370b330f5cc5cabe850838031af to your computer and use it in GitHub Desktop.
Save tyanmahou/45341370b330f5cc5cabe850838031af to your computer and use it in GitHub Desktop.
range options
#include<iostream>
#include<vector>
#include"Range.hpp"
int main()
{
std::vector<int> v{ 1,2,3,4,5 };
for (auto[elm, i] : v - range::with_index)
{
elm *= i;
}
for (auto[elm, i] : std::as_const(v) - range::with_index)
{
std::cout << "Index:" << i << " value:"<<elm << std::endl;
}
return 0;
}
#pragma once
#include<iterator>
namespace range
{
template<class Range>
using range_value_t = typename std::iterator_traits<decltype(std::begin(std::declval<Range&>()))>::value_type;
template<class Range>
using range_iterator_t = decltype(std::begin(std::declval<Range&>()));
template<class Range>
using range_const_iterator_t = decltype(std::cbegin(std::declval<Range&>()));
namespace detail
{
//pair(普通のstd::pairでも良い)
template<class T>
struct WithIndexPair
{
T value;
const std::size_t index;
};
//イテレーター
template<class It>
class WithIndexIterator
{
public:
using iterator_category = std::bidirectional_iterator_tag;
using difference_type = std::size_t;
using value_type = WithIndexPair<decltype(*std::declval<It>())&>;
using pointer = value_type*;
using reference = value_type&;
private:
It m_iterator;
std::size_t m_index;
public:
WithIndexIterator(It it, std::size_t index) :
m_iterator(it),
m_index(index)
{}
value_type operator *()const
{
return { *m_iterator, m_index };
}
value_type* operator ->()const
{
return &*(*this);
}
WithIndexIterator& operator ++()
{
++m_iterator;
++m_index;
return *this;
}
WithIndexIterator& operator --()
{
--m_iterator;
--m_index;
return *this;
}
bool operator ==(const WithIndexIterator& other)const
{
return m_iterator == other.m_iterator;
}
bool operator !=(const WithIndexIterator& other)const
{
return m_iterator != other.m_iterator;
}
};
template<class Range>
class WithIndexRange
{
using iterator = WithIndexIterator<range_iterator_t<Range>>;
using const_iterator = WithIndexIterator<range_const_iterator_t<const Range>>;
private:
Range m_range;
public:
WithIndexRange(Range&& range) :
m_range(std::forward<Range>(range))
{}
iterator begin()
{
return { std::begin(m_range),0 };
}
iterator end()
{
return { std::end(m_range) , std::size(m_range) };
}
const_iterator begin()const
{
return const_iterator{ std::begin(m_range),0 };
}
const_iterator end()const
{
return const_iterator{ std::end(m_range) , std::size(m_range) };
}
std::size_t size()const
{
return std::size(m_range);
}
};
}
//添え字付き
constexpr struct _WithIndex_OP
{
template<class Range>
auto operator()(Range&& v)const
{
return detail::WithIndexRange<Range>(std::forward<Range>(v));
}
template<class Range>
friend auto operator -(Range&& v, _WithIndex_OP op)
{
return op(std::forward<Range>(v));
}
}withIndex;
namespace detail
{
template<class Range>
class ReverseRange
{
using iterator = std::reverse_iterator<range_iterator_t<Range>>;
using const_iterator = std::reverse_iterator<range_const_iterator_t<Range>>;
private:
Range m_range;
public:
ReverseRange(Range&& range) :
m_range(std::forward<Range>(range))
{}
iterator begin()
{
return iterator{ std::end(m_range) };
}
iterator end()
{
return iterator{ std::begin(m_range) };
}
const_iterator begin()const
{
return const_iterator{ std::end(m_range) };
}
const_iterator end()const
{
return const_iterator{ std::begin(m_range) };
}
std::size_t size()const
{
return std::size(m_range);
}
};
}
//逆順
constexpr struct _Reverse_OP
{
template<class Range>
detail::ReverseRange<Range> operator ()(Range&& v)const
{
return detail::ReverseRange<Range>(std::forward<Range>(v));
}
template<class Range>
friend auto operator -(Range&& v, _Reverse_OP op)
{
return op(std::forward<Range>(v));
}
}reverse;
}

範囲ベースforにindexをつける

range::with_index

range::with_index_const

範囲ベースforを逆順でまわす

range::reverse

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment