Last active
October 31, 2017 09:09
-
-
Save tyanmahou/45341370b330f5cc5cabe850838031af to your computer and use it in GitHub Desktop.
range options
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment