mbed-os5 only for TYBLE16

Dependents:   TYBLE16_simple_data_logger TYBLE16_MP3_Air

Revision:
1:9db0e321a9f4
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/platform/cxxsupport/mstd_utility	Tue Dec 31 06:02:27 2019 +0000
@@ -0,0 +1,341 @@
+/* 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_UTILITY_
+#define MSTD_UTILITY_
+
+/* <mstd_utility>
+ *
+ * - includes toolchain's <utility>
+ * - For ARM C 5, standard C++11/14 features:
+ *   - include <initializer_list>
+ *   - std::move, std::forward, std::exchange
+ *   - std::declval
+ *   - std::integer_sequence
+ *   - include <algorithm> to get default std::swap
+ *   - mstd::swap - substitute for std::swap that can move
+ *   - std::swap(array)
+ * - Swap assistance, to ensure moves happen on ARM C 5
+ *   - mstd::swap - alias for std::swap, or a local moving implementation for ARM C 5
+ * - For all toolchains, C++17/20 backports:
+ *   - mstd::as_const
+ */
+
+#include <utility>
+
+#ifdef __CC_ARM
+#include <_move.h>
+#include <algorithm> // to get std::swap
+#include <cstddef>
+#include <initializer_list>
+#include <cstdint> // uintmax_t
+#include <mstd_type_traits>
+#endif
+
+
+namespace mstd {
+// [utility.swap] - ARMC5's std::swap is not C++11, so make sure mstd::swap is
+// So to get ADL-aware lookup with good default swap, users should do `using mstd::swap; swap(x, y);`.
+#ifdef __CC_ARM
+template <class _TypeT>
+void swap(_TypeT &__a, _TypeT &__b)
+noexcept(__is_nothrow_constructible(_TypeT, _TypeT &&) && __is_nothrow_assignable(_TypeT &, _TypeT &&))
+{
+    _TypeT __tmp = std::move(__a);
+    __a = std::move(__b);
+    __b = std::move(__tmp);
+}
+
+template <class _TypeT, std::size_t _Size>
+void swap(_TypeT (&__a)[_Size], _TypeT (&__b)[_Size])
+noexcept(noexcept(swap(*__a, *__b)))
+{
+    _TypeT *__ptr_a = __a, *__ptr_b = __b;
+    const _TypeT * const __end_a = __a + _Size;
+    for (; __ptr_a != __end_a; ++__ptr_a, ++__ptr_b) {
+        swap(*__ptr_a, *__ptr_b);
+    }
+}
+#else
+using std::swap;
+#endif
+
+} // namespace mstd
+
+
+#ifdef __CC_ARM
+
+namespace std {
+
+template <typename _TypeT>
+constexpr conditional_t<!is_nothrow_move_constructible<_TypeT>::value && is_copy_constructible<_TypeT>::value,
+                        const _TypeT &, _TypeT &&>
+move_if_noexcept(_TypeT &__t) noexcept
+{
+    return std::move(__t);
+}
+
+// [declval]
+// is provided by mstd_type_traits, which we include
+
+// [utility.swap] - ARMC5's basic swap in <algorithm> does not move, but
+// we can add this std overload for arrays, and send it to our mstd moving version
+template <class _TypeT, std::size_t _Size>
+void swap(_TypeT (&__a)[_Size], _TypeT (&__b)[_Size])
+noexcept(noexcept(mstd::swap(*__a, *__b)))
+{
+    mstd::swap(__a, __b);
+}
+
+// [intseq.intseq]
+template <typename T, T... I>
+struct integer_sequence {
+    using value_type = T;
+    static constexpr size_t size() noexcept { return sizeof...(I); }
+};
+
+template <size_t... I>
+using index_sequence = integer_sequence<size_t, I...>;
+
+// [intseq.make]
+namespace impl {
+
+template <typename seq1, typename seq2>
+struct combine_umax_sequences;
+
+template <uintmax_t... seq1, uintmax_t... seq2>
+struct combine_umax_sequences<integer_sequence<uintmax_t, seq1...>, integer_sequence<uintmax_t, seq2...>>
+    : mstd::type_identity<integer_sequence<uintmax_t, seq1..., sizeof...(seq1) + seq2...>> { };
+
+template <uintmax_t N>
+struct make_umax_sequence : combine_umax_sequences<typename make_umax_sequence<N / 2>::type,
+                                                   typename make_umax_sequence<N - N / 2>::type> { };
+
+template <>
+struct make_umax_sequence<1> : mstd::type_identity<integer_sequence<uintmax_t, 0>> { };
+
+template <>
+struct make_umax_sequence<0> : mstd::type_identity<integer_sequence<uintmax_t>> { };
+
+
+template <typename T, T N, typename useq = typename make_umax_sequence<N>::type>
+struct make_integer_sequence;
+
+template <typename T, T N, uintmax_t... I>
+struct make_integer_sequence<T, N, integer_sequence<uintmax_t, I...>> {
+    static_assert(N >= 0, "negative integer sequence");
+    using type = integer_sequence<T, static_cast<T>(I)...>;
+};
+}
+
+template <typename T, T N>
+using make_integer_sequence = typename impl::make_integer_sequence<T, N>::type;
+
+template <size_t N>
+using make_index_sequence = make_integer_sequence<size_t, N>;
+
+template <typename... T>
+using index_sequence_for = make_index_sequence<sizeof...(T)>;
+
+
+// [pair.astuple]
+template <typename>
+struct tuple_size;
+
+template <size_t, typename>
+struct tuple_element;
+
+template <size_t I, typename T>
+using tuple_element_t = typename tuple_element<I, T>::type;
+
+template <typename T1, typename T2>
+struct tuple_size<pair<T1, T2>> : integral_constant<size_t, 2> { };
+
+template <typename T1, typename T2>
+struct tuple_element<0, pair<T1, T2>> : mstd::type_identity<T1> { };
+
+template <typename T1, typename T2>
+struct tuple_element<1, pair<T1, T2>> : mstd::type_identity<T2> { };
+
+namespace impl{
+
+template <size_t I>
+struct pair_getter;
+
+template <>
+struct pair_getter<0> {
+    template <typename T1, typename T2>
+    static T1 &get(pair<T1, T2> &p)
+    {
+        return p.first;
+    }
+    template <typename T1, typename T2>
+    static const T1 &cget(const pair<T1, T2> &p)
+    {
+        return p.first;
+    }
+    template <typename T1, typename T2>
+    static T1 &&get_move(pair<T1, T2> &&p)
+    {
+        return std::forward<T1>(p.first);
+    }
+    template <typename T1, typename T2>
+    static const T1 &&cget_move(const pair<T1, T2> &&p)
+    {
+        return std::forward<T1>(p.first);
+    }
+};
+
+template <>
+struct pair_getter<1> {
+    template <typename T1, typename T2>
+    static T2 &get(pair<T1, T2> &p)
+    {
+        return p.second;
+    }
+    template <typename T1, typename T2>
+    static const T2 &cget(const pair<T1, T2> &p)
+    {
+        return p.second;
+    }
+    template <typename T1, typename T2>
+    static T2 &&get_move(pair<T1, T2> &&p)
+    {
+        return std::forward<T2>(p.second);
+    }
+    template <typename T1, typename T2>
+    static const T2 &&cget_move(const pair<T1, T2> &&p)
+    {
+        return std::forward<T2>(p.second);
+    }
+};
+}
+
+template <size_t I, typename T1, typename T2>
+constexpr tuple_element_t<I, pair<T1, T2>> &get(pair<T1, T2> &p) noexcept
+{
+    return impl::pair_getter<I>::get(p);
+}
+
+template <size_t I, typename T1, typename T2>
+constexpr const tuple_element_t<I, pair<T1, T2>> &get(const pair<T1, T2> &p) noexcept
+{
+    return impl::pair_getter<I>::cget(p);
+}
+
+template <size_t I, typename T1, typename T2>
+constexpr tuple_element_t<I, pair<T1, T2>> &&get(pair<T1, T2> &&p) noexcept
+{
+    return impl::pair_getter<I>::get_move(std::move(p));
+}
+
+template <size_t I, typename T1, typename T2>
+constexpr const tuple_element_t<I, pair<T1, T2>> &&get(const pair<T1, T2> &&p) noexcept
+{
+    return impl::pair_getter<I>::cget_move(std::move(p));
+}
+
+template <typename T1, typename T2>
+constexpr T1 &get(pair<T1, T2> &p) noexcept
+{
+    return p.first;
+}
+
+template <typename T1, typename T2>
+constexpr const T1 &get(const pair<T1, T2> &p) noexcept
+{
+    return p.first;
+}
+
+template <typename T1, typename T2>
+constexpr T1 &&get(pair<T1, T2> &&p) noexcept
+{
+    return p.first;
+}
+
+template <typename T1, typename T2>
+constexpr const T1 &&get(const pair<T1, T2> &&p) noexcept
+{
+    return p.first;
+}
+
+template <typename T2, typename T1>
+constexpr T2 &get(pair<T1, T2> &p) noexcept
+{
+    return p.second;
+}
+
+template <typename T2, typename T1>
+constexpr const T2 &get(const pair<T1, T2> &p) noexcept
+{
+    return p.second;
+}
+
+template <typename T2, typename T1>
+constexpr T2 &&get(pair<T1, T2> &&p) noexcept
+{
+    return p.second;
+}
+
+template <typename T2, typename T1>
+constexpr const T2 &&get(const pair<T1, T2> &&p) noexcept
+{
+    return p.second;
+}
+
+
+} // namespace std
+#endif
+
+namespace mstd {
+namespace rel_ops { using namespace std::rel_ops; }
+using std::initializer_list;
+using std::exchange;
+using std::forward;
+using std::move;
+// No exceptions in mbed OS
+template <typename T>
+T &&move_if_noexcept(T &t) noexcept
+{
+    return mstd::move(t);
+}
+using std::declval;
+using std::make_pair;
+using std::get;
+using std::pair;
+using std::integer_sequence;
+using std::index_sequence;
+using std::make_integer_sequence;
+using std::make_index_sequence;
+using std::index_sequence_for;
+
+// C++17 [utility.as_const] */
+#if __cpp_lib_as_const >= 201510
+using std::as_const;
+#else
+template <typename _TypeT>
+constexpr std::add_const_t<_TypeT> &as_const(_TypeT &__t) noexcept
+{
+    return __t;
+}
+
+template <typename _TypeT>
+void as_const(_TypeT &&) = delete;
+#endif
+
+} // namespace mstd
+
+#endif // MSTD_UTILITY_