mbed-os5 only for TYBLE16
Dependents: TYBLE16_simple_data_logger TYBLE16_MP3_Air
Diff: platform/cxxsupport/mstd_iterator
- Revision:
- 1:9db0e321a9f4
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/platform/cxxsupport/mstd_iterator Tue Dec 31 06:02:27 2019 +0000 @@ -0,0 +1,460 @@ +/* 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_