Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #pragma once
- #include<type_traits>
- namespace range
- {
- namespace detail
- {
- //イテレーター
- template<class It>
- class WithIndexIterator
- {
- using value_type = std::remove_reference_t<decltype(*std::declval<It&>())>;
- private:
- It m_iterator;
- std::size_t m_index;
- public:
- WithIndexIterator(It it, std::size_t index) :
- m_iterator(it),
- m_index(index)
- {}
- decltype(auto) operator *()const
- {
- struct
- {
- value_type& value;
- const std::size_t index;
- }ret{ *m_iterator,m_index };
- return ret;
- }
- decltype(auto) operator ->()const
- {
- return &*(*this);
- }
- WithIndexIterator& operator ++()
- {
- ++m_iterator;
- ++m_index;
- return *this;
- }
- bool operator !=(const WithIndexIterator& other)const
- {
- return m_iterator != other.m_iterator;
- }
- };
- template<class T, bool isConst = false>
- class WithIndexRange
- {
- using iterator = std::conditional_t<isConst, decltype(std::declval<T&>().cbegin()), decltype(std::declval<T&>().begin())>;
- private:
- T& m_range;
- public:
- WithIndexRange(T& range) :
- m_range(range)
- {}
- WithIndexIterator<iterator> begin()const
- {
- return { m_range.begin(),0 };
- }
- WithIndexIterator<iterator> end()const
- {
- return { m_range.end() , m_range.size() };
- }
- };
- //生配列への特殊化
- template<class T, int N, bool isConst>
- class WithIndexRange<T(&)[N], isConst>
- {
- using iterator = std::conditional_t<isConst, const T*, T*>;
- private:
- iterator m_begin;
- iterator m_end;
- std::size_t m_size;
- public:
- WithIndexRange(T(&range)[N]) :
- m_begin(range),
- m_end(&range[N]),
- m_size(N)
- {}
- WithIndexIterator<iterator> begin()const
- {
- return { m_begin,0 };
- }
- WithIndexIterator<iterator> end()const
- {
- return { m_end ,N - 1 };
- }
- };
- }
- constexpr struct WithIndex_t
- {
- template<class T>
- friend detail::WithIndexRange<T> operator ,(T&& v, WithIndex_t)
- {
- return detail::WithIndexRange<T>(v);
- }
- }with_index;
- constexpr struct WithIndexConst_t
- {
- template<class T>
- friend detail::WithIndexRange<T, true> operator ,(T&& v, WithIndexConst_t)
- {
- return detail::WithIndexRange<T, true>(v);
- }
- }with_index_const;
- }
Add Comment
Please, Sign In to add comment