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_functional	Tue Dec 31 06:02:27 2019 +0000
@@ -0,0 +1,499 @@
+/* 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 tUNChe License.
+ */
+#ifndef MSTD_FUNCTIONAL_
+#define MSTD_FUNCTIONAL_
+
+/* <mstd_functional>
+ *
+ * - includes toolchain's <functional>
+ * - For ARM C 5, standard C++11/14 features:
+ *   - std::mem_fn,
+ *   - std::reference_wrapper, std::ref, std::cref
+ *   - transparent std::plus<> etc
+ *   - std::bit_and, std::bit_or, std::bit_xor, std::bit_not
+ * - For all toolchains, C++17/20 backports:
+ *   - mstd::not_fn (C++17)
+ *   - mstd::invoke (C++17)
+ *   - mstd::unwrap_reference, mstd::unwrap_ref_decay (C++20)
+ */
+
+#include <functional>
+
+#include <mstd_memory> // addressof
+#include <mstd_utility> // forward
+#include <mstd_type_traits>
+
+#ifdef __CC_ARM
+
+namespace std
+{
+// [func.memfn]
+namespace impl {
+template <typename R, typename T>
+class mem_fn_t {
+    R T::* pm;
+public:
+    mem_fn_t(R T::* pm) : pm(pm) { }
+    template <typename... Args>
+    invoke_result_t<R T::*, Args...> operator()(Args&&... args) const
+    {
+        return std::invoke(pm, std::forward<Args>(args)...);
+    }
+};
+}
+
+template <class R, class T>
+impl::mem_fn_t<R, T> mem_fn(R T::* pm)
+{
+    return impl::mem_fn_t<R, T>(pm);
+}
+
+} // namespace std
+
+#endif // __CC_ARM
+
+namespace mstd {
+
+// [func.invoke]
+#if __cpp_lib_invoke >= 201411
+using std::invoke;
+#else
+template <typename F, typename... Args>
+invoke_result_t<F, Args...> invoke(F&& f, Args&&... args)
+{
+    return impl::INVOKE(std::forward<F>(f), std::forward<Args>(args)...);
+}
+#endif // __cpp_lib_invoke
+
+} // namespace mstd
+
+#ifdef __CC_ARM
+namespace std {
+
+    using mstd::invoke;
+
+// [refwrap]
+template <typename T>
+class reference_wrapper {
+    T *ptr;
+public:
+    using type = T;
+    // [refwrap.const]
+    // LWG 2993 version of constructor does not seem to work in ARM C 5, so stick with
+    // this original version.
+    reference_wrapper(T &x) noexcept : ptr(addressof(x)) { }
+    reference_wrapper(T &&x) = delete;
+
+    reference_wrapper(const reference_wrapper &) noexcept = default;
+    // [refwrap.assign]
+    reference_wrapper &operator=(const reference_wrapper &) noexcept = default;
+
+    // [refwrap.access]
+    operator T &() const noexcept { return *ptr; }
+    T &get() const noexcept { return *ptr; }
+
+    // [refwrap.invoke]
+    template <typename... ArgTypes>
+    invoke_result_t<T &, ArgTypes...> operator()(ArgTypes&&... args) const
+    {
+        return std::invoke(get(), forward<ArgTypes>(args)...);
+    }
+};
+
+// [refwrap.helpers]
+template <typename T>
+reference_wrapper<T> ref(T &t) noexcept
+{
+    return reference_wrapper<T>(t);
+}
+
+template <typename T>
+reference_wrapper<T> ref(reference_wrapper<T> &t) noexcept
+{
+    return ref(t.get());
+}
+
+template <typename T>
+void ref(const T &&) = delete;
+
+template <typename T>
+reference_wrapper<const T> cref(const T &t) noexcept
+{
+    return reference_wrapper<const T>(t);
+}
+
+template <typename T>
+reference_wrapper<const T> cref(reference_wrapper<T> &t) noexcept
+{
+    return cref(t.get());
+}
+
+template <typename T>
+void cref(const T &&) = delete;
+
+// ARMC5 has basic plus<T> etc - we can add plus<void> specialisations;
+// and the language rules allow us to add the default void arguments missing
+// from its header.
+
+template <typename T = void> struct plus;
+template <typename T = void> struct minus;
+template <typename T = void> struct multiplies;
+template <typename T = void> struct divides;
+template <typename T = void> struct modulus;
+template <typename T = void> struct negate;
+template <typename T = void> struct equal_to;
+template <typename T = void> struct not_equal_to;
+template <typename T = void> struct greater;
+template <typename T = void> struct less;
+template <typename T = void> struct greater_equal;
+template <typename T = void> struct less_equal;
+template <typename T = void> struct logical_and;
+template <typename T = void> struct logical_or;
+template <typename T = void> struct logical_not;
+
+// [arithmetic.operations.plus]
+template <>
+struct plus<void> {
+    using is_transparent = true_type;
+    template <typename T, typename U>
+    constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) + std::forward<U>(u))
+    {
+        return std::forward<T>(t) + std::forward<U>(u);
+    }
+};
+
+// [arithmetic.operations.minus]
+template <>
+struct minus<void> {
+    using is_transparent = true_type;
+    template <typename T, typename U>
+    constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) - std::forward<U>(u))
+    {
+        return std::forward<T>(t) - std::forward<U>(u);
+    }
+};
+
+// [arithmetic.operations.multiplies]
+template <>
+struct multiplies<void> {
+    using is_transparent = true_type;
+    template <typename T, typename U>
+    constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) * std::forward<U>(u))
+    {
+        return std::forward<T>(t) * std::forward<U>(u);
+    }
+};
+
+// [arithmetic.operations.divides]
+template <>
+struct divides<void> {
+    using is_transparent = true_type;
+    template <typename T, typename U>
+    constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) / std::forward<U>(u))
+    {
+        return std::forward<T>(t) / std::forward<U>(u);
+    }
+};
+
+// [arithmetic.operations.modulus]
+template <>
+struct modulus<void> {
+    using is_transparent = true_type;
+    template <typename T, typename U>
+    constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) % std::forward<U>(u))
+    {
+        return std::forward<T>(t) % std::forward<U>(u);
+    }
+};
+
+// [arithmetic.operations.negate]
+template <>
+struct negate<void> {
+    using is_transparent = true_type;
+    template <typename T>
+    constexpr auto operator()(T&& t) const -> decltype(-std::forward<T>(t))
+    {
+        return -std::forward<T>(t);
+    }
+};
+
+// [comparisons.equal_to]
+template <>
+struct equal_to<void> {
+    using is_transparent = true_type;
+    template <typename T, typename U>
+    constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) == std::forward<U>(u))
+    {
+        return std::forward<T>(t) == std::forward<U>(u);
+    }
+};
+
+// [comparisons.not_equal_to]
+template <>
+struct not_equal_to<void> {
+    using is_transparent = true_type;
+    template <typename T, typename U>
+    constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) != std::forward<U>(u))
+    {
+        return std::forward<T>(t) != std::forward<U>(u);
+    }
+};
+
+// [comparisons.greater]
+template <>
+struct greater<void> {
+    using is_transparent = true_type;
+    template <typename T, typename U>
+    constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) > std::forward<U>(u))
+    {
+        return std::forward<T>(t) > std::forward<U>(u);
+    }
+};
+
+// [comparisons.less]
+template <>
+struct less<void> {
+    using is_transparent = true_type;
+    template <typename T, typename U>
+    constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) < std::forward<U>(u))
+    {
+        return std::forward<T>(t) < std::forward<U>(u);
+    }
+};
+
+// [comparisons.greater_equal]
+template <>
+struct greater_equal<void> {
+    using is_transparent = true_type;
+    template <typename T, typename U>
+    constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) >= std::forward<U>(u))
+    {
+        return std::forward<T>(t) >= std::forward<U>(u);
+    }
+};
+
+// [comparisons.less_equal]
+template <>
+struct less_equal<void> {
+    using is_transparent = true_type;
+    template <typename T, typename U>
+    constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) <= std::forward<U>(u))
+    {
+        return std::forward<T>(t) <= std::forward<U>(u);
+    }
+};
+
+// [logical.operations.and]
+template <>
+struct logical_and<void> {
+    using is_transparent = true_type;
+    template <typename T, typename U>
+    constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) && std::forward<U>(u))
+    {
+        return std::forward<T>(t) && std::forward<U>(u);
+    }
+};
+
+// [logical.operations.or]
+template <>
+struct logical_or<void> {
+    using is_transparent = true_type;
+    template <typename T, typename U>
+    constexpr auto operator()(T&& t, U&& u) const -> decltype(std::forward<T>(t) || std::forward<U>(u))
+    {
+        return std::forward<T>(t) || std::forward<U>(u);
+    }
+};
+
+// [logical.operations.not]
+template <>
+struct logical_not<void> {
+    using is_transparent = true_type;
+    template <typename T>
+    constexpr auto operator()(T&& t) const -> decltype(!std::forward<T>(t))
+    {
+        return !std::forward<T>(t);
+    }
+};
+
+// [bitwise.operations.and]
+template <typename T = void>
+struct bit_and {
+    constexpr T operator()(const T &x, const T &y) const
+    {
+        return x & y;
+    }
+};
+
+template <>
+struct bit_and<void> {
+    using is_transparent = true_type;
+    template <typename T, typename U>
+    constexpr auto operator()(T&& t,U&& u) const -> decltype(std::forward<T>(t) & std::forward<U>(u))
+    {
+        return std::forward<T>(t) & std::forward<U>(u);
+    }
+};
+
+// [bitwise.operations.or]
+template <typename T = void>
+struct bit_or {
+    constexpr T operator()(const T &x, const T &y) const
+    {
+        return x & y;
+    }
+};
+
+template <>
+struct bit_or<void> {
+    using is_transparent = true_type;
+    template <typename T, typename U>
+    constexpr auto operator()(T&& t,U&& u) const -> decltype(std::forward<T>(t) | std::forward<U>(u))
+    {
+        return std::forward<T>(t) | std::forward<U>(u);
+    }
+};
+
+// [bitwise.operations.xor]
+template <typename T = void>
+struct bit_xor {
+    constexpr T operator()(const T &x, const T &y) const
+    {
+        return x ^ y;
+    }
+};
+
+template <>
+struct bit_xor<void> {
+    using is_transparent = true_type;
+    template <typename T, typename U>
+    constexpr auto operator()(T&& t,U&& u) const -> decltype(std::forward<T>(t) ^ std::forward<U>(u))
+    {
+        return std::forward<T>(t) ^ std::forward<U>(u);
+    }
+};
+
+// [bitwise.operations.not]
+template <typename T = void>
+struct bit_not {
+    constexpr T operator()(const T &arg) const
+    {
+        return ~arg;
+    }
+};
+
+template <>
+struct bit_not<void> {
+    using is_transparent = true_type;
+    template <typename T>
+    constexpr auto operator()(T&& arg) const -> decltype(~std::forward<T>(arg))
+    {
+        return ~std::forward<T>(arg);
+    }
+};
+
+} // namespace std
+
+#endif // __CC_ARM
+
+namespace mstd {
+using std::reference_wrapper;
+using std::ref;
+using std::cref;
+using std::plus;
+using std::minus;
+using std::multiplies;
+using std::divides;
+using std::modulus;
+using std::negate;
+using std::equal_to;
+using std::not_equal_to;
+using std::greater;
+using std::less;
+using std::greater_equal;
+using std::less_equal;
+using std::logical_and;
+using std::logical_or;
+using std::logical_not;
+using std::bit_and;
+using std::bit_or;
+using std::bit_xor;
+using std::bit_not;
+
+#if __cpp_lib_not_fn >= 201603
+using std::not_fn;
+#else
+namespace impl {
+// [func.not_fn]
+template <typename F>
+class not_fn_t {
+    std::decay_t<F> fn;
+public:
+    explicit not_fn_t(F&& f) : fn(std::forward<F>(f)) { }
+    not_fn_t(const not_fn_t &other) = default;
+    not_fn_t(not_fn_t &&other) = default;
+
+    template<typename... Args>
+    auto operator()(Args&&... args) & -> decltype(!std::declval<invoke_result_t<std::decay_t<F> &, Args...>>())
+    {
+        return !mstd::invoke(fn, std::forward<Args>(args)...);
+    }
+
+    template<typename... Args>
+    auto operator()(Args&&... args) const & -> decltype(!std::declval<invoke_result_t<std::decay_t<F> const &, Args...>>())
+    {
+        return !mstd::invoke(fn, std::forward<Args>(args)...);
+    }
+
+    template<typename... Args>
+    auto operator()(Args&&... args) && -> decltype(!std::declval<invoke_result_t<std::decay_t<F>, Args...>>())
+    {
+        return !mstd::invoke(std::move(fn), std::forward<Args>(args)...);
+    }
+
+    template<typename... Args>
+    auto operator()(Args&&... args) const && -> decltype(!std::declval<invoke_result_t<std::decay_t<F> const, Args...>>())
+    {
+        return !mstd::invoke(std::move(fn), std::forward<Args>(args)...);
+    }
+};
+}
+
+template <typename F>
+impl::not_fn_t<F> not_fn(F&& f)
+{
+    return impl::not_fn_t<F>(std::forward<F>(f));
+}
+#endif
+
+/* C++20 unwrap_reference */
+template <typename T>
+struct unwrap_reference : type_identity<T> { };
+template <typename T>
+struct unwrap_reference<std::reference_wrapper<T>> : type_identity<T &> { };
+template <typename T>
+using unwrap_reference_t = typename unwrap_reference<T>::type;
+
+/* C++20 unwrap_ref_decay */
+template <typename T>
+struct unwrap_ref_decay : unwrap_reference<std::decay_t<T>> { };
+template <typename T>
+using unwrap_ref_decay_t = typename unwrap_ref_decay<T>::type;
+
+}
+
+#endif // MSTD_FUNCTIONAL_