mirror of https://github.com/ARMmbed/mbed-os.git
				
				
				
			
		
			
				
	
	
		
			461 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Plaintext
		
	
	
			
		
		
	
	
			461 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			Plaintext
		
	
	
/* mbed Microcontroller Library
 | 
						|
 * Copyright (c) 2019 ARM Limited
 | 
						|
 * SPDX-License-Identifier: Apache-2.0
 | 
						|
 *
 | 
						|
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
						|
 * you may not use this file except in compliance with the License.
 | 
						|
 * You may obtain a copy of the License at
 | 
						|
 *
 | 
						|
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
						|
 *
 | 
						|
 * Unless required by applicable law or agreed to in writing, software
 | 
						|
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
						|
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
						|
 * See the License for the specific language governing permissions and
 | 
						|
 * limitations under the License.
 | 
						|
 */
 | 
						|
#ifndef MSTD_ITERATOR_
 | 
						|
#define MSTD_ITERATOR_
 | 
						|
 | 
						|
/* <mstd_iterator>
 | 
						|
 *
 | 
						|
 * - includes toolchain's <iterator>
 | 
						|
 * - For ARM C 5, C++11/14 features:
 | 
						|
 *   - std::begin, std::end, etc
 | 
						|
 *   - std::make_reverse_iterator
 | 
						|
 *   - std::move_iterator, std::make_move_iterator
 | 
						|
 * - For all toolchains, C++17/20 backports:
 | 
						|
 *   - mstd::size
 | 
						|
 *   - mstd::ssize
 | 
						|
 *   - mstd::empty
 | 
						|
 *   - mstd::data
 | 
						|
 */
 | 
						|
 | 
						|
#include <iterator>
 | 
						|
#include <mstd_type_traits>
 | 
						|
 | 
						|
#ifdef __CC_ARM
 | 
						|
 | 
						|
#include <mstd_cstddef> // size_t
 | 
						|
 | 
						|
namespace std {
 | 
						|
 | 
						|
template <typename E>
 | 
						|
struct initializer_list;
 | 
						|
 | 
						|
// [iterator.operations]
 | 
						|
template <typename ForwardIterator>
 | 
						|
ForwardIterator next(ForwardIterator x, typename iterator_traits<ForwardIterator>::difference_type n = 1)
 | 
						|
{
 | 
						|
    advance(x, n);
 | 
						|
    return x;
 | 
						|
}
 | 
						|
 | 
						|
template <typename BidirectionalIterator>
 | 
						|
BidirectionalIterator prev(BidirectionalIterator x, typename iterator_traits<BidirectionalIterator>::difference_type n = 1)
 | 
						|
{
 | 
						|
    advance(x, -n);
 | 
						|
    return x;
 | 
						|
}
 | 
						|
 | 
						|
// [reverse.iter.make]
 | 
						|
template <typename Iterator>
 | 
						|
reverse_iterator<Iterator> make_reverse_iterator(Iterator i)
 | 
						|
{
 | 
						|
    return reverse_iterator<Iterator>(i);
 | 
						|
}
 | 
						|
 | 
						|
// [move.iterators]
 | 
						|
template <typename Iterator>
 | 
						|
class move_iterator {
 | 
						|
    Iterator current;
 | 
						|
    using R = typename iterator_traits<Iterator>::reference;
 | 
						|
public:
 | 
						|
    using iterator_type = Iterator;
 | 
						|
    using iterator_category = typename iterator_traits<Iterator>::iterator_category;
 | 
						|
    using value_type = typename iterator_traits<Iterator>::value_type;
 | 
						|
    using difference_type = typename iterator_traits<Iterator>::difference_type;
 | 
						|
    using pointer = Iterator;
 | 
						|
    using reference = conditional_t<is_reference<R>::value,
 | 
						|
                                    remove_reference_t<R> &&,
 | 
						|
                                    R>;
 | 
						|
 | 
						|
    // [move.iter.op.const]
 | 
						|
    constexpr move_iterator() : current() { }
 | 
						|
    constexpr explicit move_iterator(Iterator i) : current(i) { }
 | 
						|
 | 
						|
    template <typename U>
 | 
						|
    constexpr move_iterator(const move_iterator<U> &u) : current(u.base()) { }
 | 
						|
 | 
						|
    // [move.iter.op=]
 | 
						|
    template <typename U>
 | 
						|
    move_iterator &operator=(const move_iterator<U> &u)
 | 
						|
    {
 | 
						|
        current = u.base();
 | 
						|
        return *this;
 | 
						|
    }
 | 
						|
 | 
						|
    // [move.iter.op.conv]
 | 
						|
    constexpr Iterator base() const
 | 
						|
    {
 | 
						|
        return current;
 | 
						|
    }
 | 
						|
 | 
						|
    // [move.iter.op.star]
 | 
						|
    constexpr reference operator*() const
 | 
						|
    {
 | 
						|
        return static_cast<reference>(*current);
 | 
						|
    }
 | 
						|
 | 
						|
    // [move.iter.op.ref]
 | 
						|
    constexpr pointer operator->() const
 | 
						|
    {
 | 
						|
        return current;
 | 
						|
    }
 | 
						|
 | 
						|
    // [move.iter.op.incr]
 | 
						|
    move_iterator &operator++()
 | 
						|
    {
 | 
						|
        ++current;
 | 
						|
        return *this;
 | 
						|
    }
 | 
						|
 | 
						|
    move_iterator operator++(int)
 | 
						|
    {
 | 
						|
        move_iterator tmp = *this;
 | 
						|
        ++current;
 | 
						|
        return tmp;
 | 
						|
    }
 | 
						|
 | 
						|
    // [move.iter.op.decr]
 | 
						|
    move_iterator &operator--()
 | 
						|
    {
 | 
						|
        --current;
 | 
						|
        return *this;
 | 
						|
    }
 | 
						|
 | 
						|
    move_iterator operator--(int)
 | 
						|
    {
 | 
						|
        move_iterator tmp = *this;
 | 
						|
        --current;
 | 
						|
        return tmp;
 | 
						|
    }
 | 
						|
 | 
						|
    // [move.iter.op.+]
 | 
						|
    constexpr move_iterator operator+(difference_type n) const
 | 
						|
    {
 | 
						|
        return move_iterator(current + n);
 | 
						|
    }
 | 
						|
 | 
						|
    // [move.iter.op.+=]
 | 
						|
    move_iterator &operator+=(difference_type n)
 | 
						|
    {
 | 
						|
        current += n;
 | 
						|
        return *this;
 | 
						|
    }
 | 
						|
 | 
						|
    // [move.iter.op.-]
 | 
						|
    constexpr move_iterator operator-(difference_type n) const
 | 
						|
    {
 | 
						|
        return move_iterator(current - n);
 | 
						|
    }
 | 
						|
 | 
						|
    // [move.iter.op.-=]
 | 
						|
    move_iterator &operator-=(difference_type n)
 | 
						|
    {
 | 
						|
        current -= n;
 | 
						|
        return *this;
 | 
						|
    }
 | 
						|
 | 
						|
    // [move.iter.op.index]
 | 
						|
    constexpr auto operator[](difference_type n) const -> decltype(std::move(current[n]))
 | 
						|
    {
 | 
						|
        return std::move(current[n]);
 | 
						|
    }
 | 
						|
};
 | 
						|
 | 
						|
// [move.iter.op.cmp]
 | 
						|
template <typename Iterator1, typename Iterator2>
 | 
						|
bool operator==(const move_iterator<Iterator1> &x, const move_iterator<Iterator2> &y)
 | 
						|
{
 | 
						|
    return x.base() == y.base();
 | 
						|
}
 | 
						|
 | 
						|
template <typename Iterator1, typename Iterator2>
 | 
						|
bool operator!=(const move_iterator<Iterator1> &x, const move_iterator<Iterator2> &y)
 | 
						|
{
 | 
						|
    return !(x == y);
 | 
						|
}
 | 
						|
 | 
						|
template <typename Iterator1, typename Iterator2>
 | 
						|
bool operator<(const move_iterator<Iterator1> &x, const move_iterator<Iterator2> &y)
 | 
						|
{
 | 
						|
    return x.base() < y.base();
 | 
						|
}
 | 
						|
 | 
						|
template <typename Iterator1, typename Iterator2>
 | 
						|
bool operator<=(const move_iterator<Iterator1> &x, const move_iterator<Iterator2> &y)
 | 
						|
{
 | 
						|
    return !(y < x);
 | 
						|
}
 | 
						|
 | 
						|
template <typename Iterator1, typename Iterator2>
 | 
						|
bool operator>(const move_iterator<Iterator1> &x, const move_iterator<Iterator2> &y)
 | 
						|
{
 | 
						|
    return y < x;
 | 
						|
}
 | 
						|
 | 
						|
template <typename Iterator1, typename Iterator2>
 | 
						|
bool operator>=(const move_iterator<Iterator1> &x, const move_iterator<Iterator2> &y)
 | 
						|
{
 | 
						|
    return !(x < y);
 | 
						|
}
 | 
						|
 | 
						|
// [move.iter.nonmember]
 | 
						|
template <typename Iterator1, typename Iterator2>
 | 
						|
auto operator-(const move_iterator<Iterator1> &x,
 | 
						|
               const move_iterator<Iterator2> &y) -> decltype(x.base() - y.base())
 | 
						|
{
 | 
						|
    return x.base() - y.base();
 | 
						|
}
 | 
						|
 | 
						|
template <typename Iterator>
 | 
						|
move_iterator<Iterator> operator+(typename move_iterator<Iterator>::difference_type n, const move_iterator<Iterator> &x)
 | 
						|
{
 | 
						|
    return x + n;
 | 
						|
}
 | 
						|
 | 
						|
template <typename Iterator>
 | 
						|
constexpr move_iterator<Iterator> make_move_iterator(Iterator i)
 | 
						|
{
 | 
						|
    return move_iterator<Iterator>(i);
 | 
						|
}
 | 
						|
 | 
						|
// [iterator.range]
 | 
						|
template <class C>
 | 
						|
constexpr auto begin(C &c) -> decltype(c.begin())
 | 
						|
{
 | 
						|
    return c.begin();
 | 
						|
}
 | 
						|
 | 
						|
template <class C>
 | 
						|
constexpr auto begin(const C &c) -> decltype(c.begin())
 | 
						|
{
 | 
						|
    return c.begin();
 | 
						|
}
 | 
						|
 | 
						|
template <class C>
 | 
						|
constexpr auto end(C &c) -> decltype(c.end())
 | 
						|
{
 | 
						|
    return c.end();
 | 
						|
}
 | 
						|
 | 
						|
template <class C>
 | 
						|
constexpr auto end(const C &c) -> decltype(c.end())
 | 
						|
{
 | 
						|
    return c.end();
 | 
						|
}
 | 
						|
 | 
						|
template <class T, size_t N>
 | 
						|
constexpr T *begin(T (&array)[N]) noexcept
 | 
						|
{
 | 
						|
    return array;
 | 
						|
}
 | 
						|
 | 
						|
template <class T, size_t N>
 | 
						|
constexpr T *end(T (&array)[N]) noexcept
 | 
						|
{
 | 
						|
    return array + N;
 | 
						|
}
 | 
						|
 | 
						|
template <class C>
 | 
						|
constexpr auto cbegin(const C &c) noexcept(noexcept(std::begin(c))) -> decltype(std::begin(c))
 | 
						|
{
 | 
						|
    return std::begin(c);
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
template <class C>
 | 
						|
constexpr auto cend(const C &c) noexcept(noexcept(std::end(c))) -> decltype(std::end(c))
 | 
						|
{
 | 
						|
    return std::end(c);
 | 
						|
}
 | 
						|
 | 
						|
template <class C>
 | 
						|
constexpr auto rbegin(C &c) -> decltype(c.rbegin())
 | 
						|
{
 | 
						|
    return c.rbegin();
 | 
						|
}
 | 
						|
 | 
						|
template <class C>
 | 
						|
constexpr auto rbegin(const C &c) -> decltype(c.rbegin())
 | 
						|
{
 | 
						|
    return c.rbegin();
 | 
						|
}
 | 
						|
 | 
						|
template <class C>
 | 
						|
constexpr auto rend(C &c) -> decltype(c.rend())
 | 
						|
{
 | 
						|
    return c.rend();
 | 
						|
}
 | 
						|
 | 
						|
template <class C>
 | 
						|
constexpr auto rend(const C &c) -> decltype(c.rend())
 | 
						|
{
 | 
						|
    return c.rend();
 | 
						|
}
 | 
						|
 | 
						|
template <class T, size_t N>
 | 
						|
reverse_iterator<T *> rbegin(T (&array)[N])
 | 
						|
{
 | 
						|
    return reverse_iterator<T *>(array + N);
 | 
						|
}
 | 
						|
 | 
						|
template <class T, size_t N>
 | 
						|
reverse_iterator<T *> rend(T (&array)[N])
 | 
						|
{
 | 
						|
    return reverse_iterator<T *>(array);
 | 
						|
}
 | 
						|
 | 
						|
template <class E>
 | 
						|
reverse_iterator<const E *> rbegin(initializer_list<E> il)
 | 
						|
{
 | 
						|
    return reverse_iterator<const E *>(il.end());
 | 
						|
}
 | 
						|
 | 
						|
template <class E>
 | 
						|
reverse_iterator<const E *> rend(initializer_list<E> il)
 | 
						|
{
 | 
						|
    return reverse_iterator<const E *>(il.end());
 | 
						|
}
 | 
						|
 | 
						|
template <class C>
 | 
						|
constexpr auto crbegin(const C &c) -> decltype(std::rbegin(c))
 | 
						|
{
 | 
						|
    return std::rbegin(c);
 | 
						|
}
 | 
						|
 | 
						|
template <class C>
 | 
						|
constexpr auto crend(const C &c) -> decltype(std::rend(c))
 | 
						|
{
 | 
						|
    return std::rend(c);
 | 
						|
}
 | 
						|
 | 
						|
} // namespace std
 | 
						|
#endif
 | 
						|
 | 
						|
namespace mstd {
 | 
						|
using std::initializer_list;
 | 
						|
using std::iterator_traits;
 | 
						|
// omitting deprecated std::iterator
 | 
						|
using std::input_iterator_tag;
 | 
						|
using std::output_iterator_tag;
 | 
						|
using std::forward_iterator_tag;
 | 
						|
using std::bidirectional_iterator_tag;
 | 
						|
using std::random_access_iterator_tag;
 | 
						|
using std::advance;
 | 
						|
using std::distance;
 | 
						|
using std::next;
 | 
						|
using std::prev;
 | 
						|
using std::reverse_iterator;
 | 
						|
using std::make_reverse_iterator;
 | 
						|
using std::back_insert_iterator;
 | 
						|
using std::back_inserter;
 | 
						|
using std::front_insert_iterator;
 | 
						|
using std::front_inserter;
 | 
						|
using std::insert_iterator;
 | 
						|
using std::inserter;
 | 
						|
using std::move_iterator;
 | 
						|
using std::make_move_iterator;
 | 
						|
using std::istream_iterator;
 | 
						|
using std::ostream_iterator;
 | 
						|
using std::istreambuf_iterator;
 | 
						|
using std::ostreambuf_iterator;
 | 
						|
using std::begin;
 | 
						|
using std::end;
 | 
						|
using std::cbegin;
 | 
						|
using std::cend;
 | 
						|
using std::rbegin;
 | 
						|
using std::rend;
 | 
						|
using std::crbegin;
 | 
						|
using std::crend;
 | 
						|
 | 
						|
#if __cpp_lib_nonmember_container_access >= 201411
 | 
						|
using std::size;
 | 
						|
using std::empty;
 | 
						|
using std::data;
 | 
						|
#else
 | 
						|
// [iterator.container]
 | 
						|
template <class C>
 | 
						|
constexpr auto size(const C &c) -> decltype(c.size())
 | 
						|
{
 | 
						|
    return c.size();
 | 
						|
}
 | 
						|
 | 
						|
template <class T, size_t N>
 | 
						|
constexpr size_t size(const T (&)[N]) noexcept
 | 
						|
{
 | 
						|
    return N;
 | 
						|
}
 | 
						|
 | 
						|
template <class C>
 | 
						|
constexpr auto empty(const C &c) -> decltype(c.empty())
 | 
						|
{
 | 
						|
    return c.empty();
 | 
						|
}
 | 
						|
 | 
						|
template <class T, size_t N>
 | 
						|
constexpr bool empty(T (&)[N]) noexcept
 | 
						|
{
 | 
						|
    return false;
 | 
						|
}
 | 
						|
 | 
						|
template <class E>
 | 
						|
constexpr bool empty(initializer_list<E> il)
 | 
						|
{
 | 
						|
    return il.size() == 0;
 | 
						|
}
 | 
						|
 | 
						|
template <class C>
 | 
						|
constexpr auto data(C &c) -> decltype(c.data())
 | 
						|
{
 | 
						|
    return c.data();
 | 
						|
}
 | 
						|
 | 
						|
template <class C>
 | 
						|
constexpr auto data(const C &c) -> decltype(c.data())
 | 
						|
{
 | 
						|
    return c.data();
 | 
						|
}
 | 
						|
 | 
						|
template <class T, size_t N>
 | 
						|
constexpr T *data(T (&array)[N]) noexcept
 | 
						|
{
 | 
						|
    return array;
 | 
						|
}
 | 
						|
 | 
						|
template <class E>
 | 
						|
constexpr const E *data(initializer_list<E> il)
 | 
						|
{
 | 
						|
    return il.begin();
 | 
						|
}
 | 
						|
#endif
 | 
						|
 | 
						|
// C++20
 | 
						|
template <class C>
 | 
						|
constexpr auto ssize(const C &c) -> common_type_t<ptrdiff_t, make_signed_t<decltype(c.size())>>
 | 
						|
{
 | 
						|
    return static_cast<common_type_t<ptrdiff_t, make_signed_t<decltype(c.size())>>>(c.size());
 | 
						|
}
 | 
						|
 | 
						|
template <class T, ptrdiff_t N>
 | 
						|
constexpr ptrdiff_t ssize(const T (&)[N]) noexcept
 | 
						|
{
 | 
						|
    return N;
 | 
						|
}
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
#endif // MSTD_ITERATOR_
 |