Warning, /include/gsl/util is written in an unsupported language. File is not indexed.
0001 ///////////////////////////////////////////////////////////////////////////////
0002 //
0003 // Copyright (c) 2015 Microsoft Corporation. All rights reserved.
0004 //
0005 // This code is licensed under the MIT License (MIT).
0006 //
0007 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
0008 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
0009 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
0010 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
0011 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
0012 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
0013 // THE SOFTWARE.
0014 //
0015 ///////////////////////////////////////////////////////////////////////////////
0016
0017 #ifndef GSL_UTIL_H
0018 #define GSL_UTIL_H
0019
0020 #include <gsl/assert> // for Expects
0021
0022 #include <array>
0023 #include <cstddef> // for ptrdiff_t, size_t
0024 #include <initializer_list> // for initializer_list
0025 #include <type_traits> // for is_signed, integral_constant
0026 #include <utility> // for exchange, forward
0027
0028 #if defined(__has_include) && __has_include(<version>)
0029 #include <version>
0030 #if defined(__cpp_lib_span) && __cpp_lib_span >= 202002L
0031 #include <span>
0032 #endif // __cpp_lib_span >= 202002L
0033 #endif //__has_include(<version>)
0034
0035 #if defined(_MSC_VER) && !defined(__clang__)
0036
0037 #pragma warning(push)
0038 #pragma warning(disable : 4127) // conditional expression is constant
0039
0040 #endif // _MSC_VER
0041
0042 #if defined(__cplusplus) && (__cplusplus >= 201703L)
0043 #define GSL_NODISCARD [[nodiscard]]
0044 #else
0045 #define GSL_NODISCARD
0046 #endif // defined(__cplusplus) && (__cplusplus >= 201703L)
0047
0048 namespace gsl
0049 {
0050 //
0051 // GSL.util: utilities
0052 //
0053
0054 // index type for all container indexes/subscripts/sizes
0055 using index = std::ptrdiff_t;
0056
0057 // final_action allows you to ensure something gets run at the end of a scope
0058 template <class F>
0059 class final_action
0060 {
0061 public:
0062 static_assert(!std::is_reference<F>::value && !std::is_const<F>::value &&
0063 !std::is_volatile<F>::value,
0064 "Final_action should store its callable by value");
0065
0066 explicit final_action(F f) noexcept : f_(std::move(f)) {}
0067
0068 final_action(final_action&& other) noexcept
0069 : f_(std::move(other.f_)), invoke_(std::exchange(other.invoke_, false))
0070 {}
0071
0072 final_action(const final_action&) = delete;
0073 final_action& operator=(const final_action&) = delete;
0074 final_action& operator=(final_action&&) = delete;
0075
0076 // clang-format off
0077 GSL_SUPPRESS(f.6) // NO-FORMAT: attribute // terminate if throws
0078 // clang-format on
0079 ~final_action() noexcept
0080 {
0081 if (invoke_) f_();
0082 }
0083
0084 private:
0085 F f_;
0086 bool invoke_{true};
0087 };
0088
0089 // finally() - convenience function to generate a final_action
0090 template <class F>
0091 GSL_NODISCARD final_action<typename std::remove_cv<typename std::remove_reference<F>::type>::type>
0092 finally(F&& f) noexcept
0093 {
0094 return final_action<typename std::remove_cv<typename std::remove_reference<F>::type>::type>(
0095 std::forward<F>(f));
0096 }
0097
0098 // narrow_cast(): a searchable way to do narrowing casts of values
0099 template <class T, class U>
0100 // clang-format off
0101 GSL_SUPPRESS(type.1) // NO-FORMAT: attribute
0102 // clang-format on
0103 constexpr T narrow_cast(U&& u) noexcept
0104 {
0105 return static_cast<T>(std::forward<U>(u));
0106 }
0107
0108 //
0109 // at() - Bounds-checked way of accessing builtin arrays, std::array, std::vector
0110 //
0111 template <class T, std::size_t N>
0112 // clang-format off
0113 GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
0114 GSL_SUPPRESS(bounds.2) // NO-FORMAT: attribute
0115 // clang-format on
0116 constexpr T& at(T (&arr)[N], const index i)
0117 {
0118 Expects(i >= 0 && i < narrow_cast<index>(N));
0119 return arr[narrow_cast<std::size_t>(i)];
0120 }
0121
0122 template <class Cont>
0123 // clang-format off
0124 GSL_SUPPRESS(bounds.4) // NO-FORMAT: attribute
0125 GSL_SUPPRESS(bounds.2) // NO-FORMAT: attribute
0126 // clang-format on
0127 constexpr auto at(Cont& cont, const index i) -> decltype(cont[cont.size()])
0128 {
0129 Expects(i >= 0 && i < narrow_cast<index>(cont.size()));
0130 using size_type = decltype(cont.size());
0131 return cont[narrow_cast<size_type>(i)];
0132 }
0133
0134 template <class T>
0135 // clang-format off
0136 GSL_SUPPRESS(bounds.1) // NO-FORMAT: attribute
0137 // clang-format on
0138 constexpr T at(const std::initializer_list<T> cont, const index i)
0139 {
0140 Expects(i >= 0 && i < narrow_cast<index>(cont.size()));
0141 return *(cont.begin() + i);
0142 }
0143
0144 #if defined(__cpp_lib_span) && __cpp_lib_span >= 202002L
0145 template <class T, size_t extent = std::dynamic_extent>
0146 constexpr auto at(std::span<T, extent> sp, const index i) -> decltype(sp[sp.size()])
0147 {
0148 Expects(i >= 0 && i < narrow_cast<index>(sp.size()));
0149 return sp[gsl::narrow_cast<size_t>(i)];
0150 }
0151 #endif // __cpp_lib_span >= 202002L
0152 } // namespace gsl
0153
0154 #if defined(_MSC_VER) && !defined(__clang__)
0155
0156 #pragma warning(pop)
0157
0158 #endif // _MSC_VER
0159
0160 #endif // GSL_UTIL_H