duckstation

duckstation, but archived from the revision just before upstream changed it to a proprietary software project, this version is the libre one
git clone https://git.neptards.moe/u3shit/duckstation.git
Log | Files | Refs | README | LICENSE

dimensional_array.h (3312B)


      1 // Sourced from https://github.com/BreadFish64/ScaleFish/blob/master/common/dimensional_array.hpp
      2 // Copyright (c) 2020 BreadFish64
      3 //
      4 // Permission is hereby granted, free of charge, to any person obtaining a copy
      5 // of this software and associated documentation files (the "Software"), to deal
      6 // in the Software without restriction, including without limitation the rights
      7 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
      8 // copies of the Software, and to permit persons to whom the Software is
      9 // furnished to do so, subject to the following conditions:
     10 //
     11 // The above copyright notice and this permission notice shall be included in all
     12 // copies or substantial portions of the Software.
     13 //
     14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     19 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
     20 // SOFTWARE.
     21 
     22 #pragma once
     23 
     24 #include <array>
     25 #include <cstdint>
     26 #include <type_traits>
     27 
     28 namespace detail {
     29 template<typename T, std::size_t rank, std::size_t... sizes>
     30 struct DimensionalArrayExplicitRank;
     31 
     32 // Workaround for VS2017 & VS 16.9.x
     33 #if defined(_MSC_VER) && (_MSC_VER < 1920 || _MSC_VER == 1928)
     34 
     35 template<std::size_t rank, std::size_t... sizes>
     36 struct GetRankSize
     37 {
     38   static constexpr std::size_t size_array[] = {sizes...};
     39   static constexpr std::size_t value = size_array[rank - 1];
     40 };
     41 
     42 template<typename T, std::size_t rank, std::size_t... sizes>
     43 using GetArrayImplType =
     44   std::array<std::conditional_t<rank == 1, T, DimensionalArrayExplicitRank<T, rank - 1, sizes...>>,
     45              GetRankSize<rank, sizes...>::value>;
     46 
     47 #else
     48 
     49 template<std::size_t rank, std::size_t... sizes>
     50 constexpr std::size_t GetRankSize()
     51 {
     52   constexpr std::size_t size_array[] = {sizes...};
     53   return size_array[rank - 1];
     54 }
     55 
     56 template<typename T, std::size_t rank, std::size_t... sizes>
     57 using GetArrayImplType =
     58   std::array<std::conditional_t<rank == 1, T, DimensionalArrayExplicitRank<T, rank - 1, sizes...>>,
     59              GetRankSize<rank, sizes...>()>;
     60 
     61 #endif
     62 
     63 template<typename T, std::size_t rank_param, std::size_t... sizes>
     64 struct DimensionalArrayExplicitRank : public GetArrayImplType<T, rank_param, sizes...>
     65 {
     66   static constexpr std::size_t rank = rank_param;
     67   static_assert(rank > 0, "Attempted to create dimensional array with rank less than 1");
     68   using ArrayImplType = GetArrayImplType<T, rank, sizes...>;
     69   using ArrayImplType::ArrayImplType;
     70 
     71   template<typename Callable>
     72   void enumerate(const Callable& f)
     73   {
     74     for (auto& it : *this)
     75     {
     76       if constexpr (rank == 1)
     77         f(it);
     78       else
     79         it.enumerate(f);
     80     }
     81   }
     82 
     83   template<typename Callable>
     84   void enumerate(const Callable& f) const
     85   {
     86     for (const auto& it : *this)
     87     {
     88       if constexpr (rank == 1)
     89         f(it);
     90       else
     91         it.enumerate(f);
     92     }
     93   }
     94 };
     95 } // namespace detail
     96 
     97 template<typename T, std::size_t... sizes>
     98 using DimensionalArray = detail::DimensionalArrayExplicitRank<T, sizeof...(sizes), sizes...>;