Back to home page

EIC code displayed by LXR

 
 

    


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