読者です 読者をやめる 読者になる 読者になる

C++と色々

主にC++やプログラムに関する記事を投稿します。

to_index, to_iterator書いてみた

C++

N3450を見て、非メンバ関数版のto_index, to_iteratorなんとなく書いてみました。本当ならクラスのメンバ関数ですが、気にせずに…。

#include <iterator>
#include <type_traits>

template <class Container>
auto to_index(const Container& container, typename Container::const_iterator it)
-> decltype(std::distance(std::begin(container), it))
{
    static_assert(std::is_same<
        typename std::iterator_traits<
            typename Container::const_iterator
        >::iterator_category, std::random_access_iterator_tag
    >::value, "");
    return std::distance(std::begin(container), it);
}

template <class Container>
auto to_index(Container& container, typename Container::iterator it)
-> decltype(std::distance(std::begin(container), it))
{
    static_assert(std::is_same<
        typename std::iterator_traits<
            typename Container::iterator
        >::iterator_category, std::random_access_iterator_tag
    >::value, "");
    return std::distance(std::begin(container), it);
}

template <class Container>
auto to_iterator(const Container& container, typename Container::size_type index)
-> decltype(std::next(std::begin(container), index))
{
    static_assert(std::is_same<
        typename std::iterator_traits<
            typename Container::const_iterator
        >::iterator_category, std::random_access_iterator_tag
    >::value, "");
    return std::next(std::begin(container), index);
}

template <class Container>
auto to_iterator(Container& container, typename Container::size_type index)
-> decltype(std::next(std::begin(container), index))
{
    static_assert(std::is_same<
        typename std::iterator_traits<
            typename Container::iterator
        >::iterator_category, std::random_access_iterator_tag
    >::value, "");
    return std::next(std::begin(container), index);
}

#include <vector>
#include <algorithm>
#include <cassert>

int main()
{
    using sequence = std::vector<int>;//std::array, std::basic_string, std::dequeでも動く…はず(試してない)
    const sequence v = {10, 20, 30, 40, 50};
    const auto result = std::find(v.begin(), v.end(), 30);
    const auto index = to_index(v, result);
    const auto iter = to_iterator(v, index);
    assert(*iter == v[index]);
}

decltype(auto)使いたい…