Device interface library for multiple platforms including Mbed.
Dependents: DeepCover Embedded Security in IoT MaximInterface MAXREFDES155#
Maxim Interface is a library framework focused on providing flexible and expressive hardware interfaces. Both communication interfaces such as I2C and 1-Wire and device interfaces such as DS18B20 are supported. Modern C++ concepts are used extensively while keeping compatibility with C++98/C++03 and requiring no external dependencies. The embedded-friendly design does not depend on exceptions or RTTI.
The full version of the project is hosted on GitLab: https://gitlab.com/iabenz/MaximInterface
Diff: MaximInterfaceCore/span.hpp
- Revision:
- 8:5ea891c7d1a1
- Parent:
- 7:9cd16581b578
- Child:
- 10:947d3f44e0a0
--- a/MaximInterfaceCore/span.hpp Mon Jul 22 11:44:07 2019 -0500 +++ b/MaximInterfaceCore/span.hpp Mon Sep 16 11:13:37 2019 -0500 @@ -1,5 +1,5 @@ /******************************************************************************* -* Copyright (C) 2018 Maxim Integrated Products, Inc., All Rights Reserved. +* Copyright (C) Maxim Integrated Products, Inc., All Rights Reserved. * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), @@ -30,11 +30,10 @@ * ownership rights. *******************************************************************************/ -#ifndef MaximInterfaceCore_span -#define MaximInterfaceCore_span +#ifndef MaximInterfaceCore_span_hpp +#define MaximInterfaceCore_span_hpp #include <stddef.h> -#include <stdint.h> #include <iterator> #include <vector> #include "array.hpp" @@ -43,7 +42,7 @@ namespace MaximInterfaceCore { /// Differentiates spans of static and dynamic extent. -static const size_t dynamic_extent = SIZE_MAX; +static const size_t dynamic_extent = static_cast<size_t>(-1); // SIZE_MAX /// @brief /// Generic memory span class similar to gsl::span and the proposed std::span. @@ -155,11 +154,60 @@ pointer data_; }; -template <typename T> struct is_array : false_type {}; +template <template <typename, size_t> class span, typename T, size_t Extent> +const typename span_base<span, T, Extent>::index_type + span_base<span, T, Extent>::extent; + +template <typename T> class has_data { + typedef char true_type[1]; + typedef char false_type[2]; + + template <typename U, U> struct check; + + template <typename U> + static true_type & test(check<typename U::pointer (U::*)(), &U::data> *); + + template <typename> static false_type & test(...); + +public: + static const bool value = (sizeof(test<T>(NULL)) == sizeof(true_type)); +}; + +template <typename T> class has_data<const T> { + typedef char true_type[1]; + typedef char false_type[2]; + + template <typename U, U> struct check; -template <typename T> struct is_array<T[]> : true_type {}; + template <typename U> + static true_type & + test(check<typename U::const_pointer (U::*)() const, &U::data> *); + + template <typename> static false_type & test(...); + +public: + static const bool value = (sizeof(test<T>(NULL)) == sizeof(true_type)); +}; + +template <typename T> class has_size { + typedef char true_type[1]; + typedef char false_type[2]; -template <typename T, size_t N> struct is_array<T[N]> : true_type {}; + template <typename U, U> struct check; + + template <typename U> + static true_type & + test(check<typename U::size_type (U::*)() const, &U::size> *); + + // Additionally support a static member function. + template <typename U> + static true_type & test(check<typename U::size_type (*)(), &U::size> *); + + template <typename> static false_type & test(...); + +public: + static const bool value = (sizeof(test<T>(NULL)) == sizeof(true_type)); +}; template <typename T> struct is_array_class_helper : false_type {}; @@ -185,16 +233,11 @@ template <typename T> struct is_vector : is_vector_helper<typename remove_cv<T>::type> {}; -// Used by the static extent span to disable the container constructors. +// Used to disable the span container constructors. template <typename T> -struct enable_if_static_extent_convertible - : enable_if<!(is_array<T>::value || is_array_class<T>::value || - is_span<T>::value || is_vector<T>::value)> {}; - -// Used by the dynamic extent span to disable the container constructors. -template <typename T> -struct enable_if_dynamic_extent_convertible - : enable_if<!(is_array<T>::value || is_span<T>::value || +struct enable_if_span_convertible + : enable_if<has_data<T>::value && has_size<T>::value && + !(is_array_class<T>::value || is_span<T>::value || is_vector<T>::value)> {}; } // namespace detail @@ -232,13 +275,12 @@ template <typename Container> span(Container & cont, - typename detail::enable_if_static_extent_convertible<Container>::type * = - NULL) + typename detail::enable_if_span_convertible<Container>::type * = NULL) : span_base(cont.data()) {} template <typename Container> span(const Container & cont, - typename detail::enable_if_static_extent_convertible<Container>::type * = + typename detail::enable_if_span_convertible<const Container>::type * = NULL) : span_base(cont.data()) {} @@ -284,6 +326,12 @@ template <size_t N> span(element_type (&arr)[N]) : span_base(arr), size_(N) {} + template <size_t N> + span(array<value_type, N> & arr) : span_base(arr.data()), size_(N) {} + + template <size_t N> + span(const array<value_type, N> & arr) : span_base(arr.data()), size_(N) {} + template <typename U, size_t N> span(const span<U, N> & s) : span_base(s.data()), size_(s.size()) {} @@ -296,17 +344,14 @@ : span_base(vec.empty() ? NULL : &vec.front()), size_(vec.size()) {} template <typename Container> - span( - Container & cont, - typename detail::enable_if_dynamic_extent_convertible<Container>::type * = - NULL) + span(Container & cont, + typename detail::enable_if_span_convertible<Container>::type * = NULL) : span_base(cont.data()), size_(cont.size()) {} template <typename Container> - span( - const Container & cont, - typename detail::enable_if_dynamic_extent_convertible<Container>::type * = - NULL) + span(const Container & cont, + typename detail::enable_if_span_convertible<const Container>::type * = + NULL) : span_base(cont.data()), size_(cont.size()) {} /// @name Observers