From ce227a4b0af7e0c737bf8262b8ffb512926055ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domagoj=20=C5=A0ari=C4=87?= Date: Mon, 8 May 2023 14:07:25 +0200 Subject: [PATCH 01/30] Clang-CL: (quick) fixed compile-time option settings. --- cmake/make_unit.cmake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/cmake/make_unit.cmake b/cmake/make_unit.cmake index 7b5b1dde..b775ce31 100644 --- a/cmake/make_unit.cmake +++ b/cmake/make_unit.cmake @@ -10,7 +10,7 @@ include(add_target_parent) ##================================================================================================== add_library(kiwaku_test INTERFACE) -if(CMAKE_CXX_COMPILER_ID MATCHES "MSVC") +if(MSVC) target_compile_options( kiwaku_test INTERFACE /W3 /EHsc /bigobj /std:c++20) elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang") target_compile_options( kiwaku_test INTERFACE -std=c++20 -Werror -Wall -Wextra -Wconversion -Wunused-variable -Wdocumentation) From 61f780a4fa469d6bbb253a6778fe9de0d26828c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domagoj=20=C5=A0ari=C4=87?= Date: Mon, 8 May 2023 14:08:08 +0200 Subject: [PATCH 02/30] Clang-CL: workaround for static-order-initialization--fiasco in TTS. --- test/tts.hpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/tts.hpp b/test/tts.hpp index d9a4ce0f..8f972c64 100644 --- a/test/tts.hpp +++ b/test/tts.hpp @@ -107,7 +107,10 @@ namespace tts::detail std::string name; tts::callable behaviour; }; - inline std::vector suite = {}; +#ifdef __clang__ // static-initialization-order-fiasco wrkrnd (actually required only for clang-cl) + __attribute__(( init_priority( 101 ) )) +#endif + inline std::vector suite; bool inline test::acknowledge(test&& f) { suite.emplace_back( std::forward(f)); From f3081524b2f9ef64adfe2d37c44a037f064acb21 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domagoj=20=C5=A0ari=C4=87?= Date: Mon, 22 May 2023 13:26:50 +0200 Subject: [PATCH 03/30] Fixed a -Wsign-conversion warning. --- include/kwk/detail/assert.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/kwk/detail/assert.hpp b/include/kwk/detail/assert.hpp index ba54cd14..6ec5a10e 100644 --- a/include/kwk/detail/assert.hpp +++ b/include/kwk/detail/assert.hpp @@ -50,7 +50,7 @@ namespace kwk [[noreturn]] inline void assert_termination(std::ostringstream & stream, char const * const condition, char const * const function, char const * const file, unsigned const line) noexcept { - boost::assertion_failed_msg(condition, std::move(stream).str().c_str(), function, file, line); + boost::assertion_failed_msg(condition, std::move(stream).str().c_str(), function, file, static_cast(line)); KWK_UNREACHABLE(); } From ac687e361866415d34f309f8919606a7d0f05779 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domagoj=20=C5=A0ari=C4=87?= Date: Wed, 19 Jul 2023 12:17:16 +0200 Subject: [PATCH 04/30] 'Some change' (I guess in kumi) prevents shape from being treated as trivial by automatically. --- include/kwk/utility/container/shape.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/kwk/utility/container/shape.hpp b/include/kwk/utility/container/shape.hpp index f40c7e3d..a309d2e5 100644 --- a/include/kwk/utility/container/shape.hpp +++ b/include/kwk/utility/container/shape.hpp @@ -74,7 +74,7 @@ namespace kwk //! @tparam D List of @ref glossary-extent types //==================================================================================================================== template - struct shape : __::prefilled_t::type + struct [[ clang::trivial_abi ]] shape : __::prefilled_t::type { using parent = typename __::prefilled_t::type; using constraint_t = KWK_DEFAULT_SHAPE_CONSTRAINTS; From c7486c82ec492d04476ee4105cdc9ea9fd4839e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domagoj=20=C5=A0ari=C4=87?= Date: Wed, 19 Jul 2023 12:19:00 +0200 Subject: [PATCH 05/30] Quick-hack fix for MB: we need default axis type to be 16 bits (a proper fix would be to make this configurable :grimace:). --- include/kwk/utility/joker.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/kwk/utility/joker.hpp b/include/kwk/utility/joker.hpp index 4ba2fa7d..8a2b7fe8 100644 --- a/include/kwk/utility/joker.hpp +++ b/include/kwk/utility/joker.hpp @@ -55,7 +55,7 @@ namespace kwk //! @ingroup utility //! @brief Joker value //! - //! The joker value defined as @ref kwk::_ is used in various context to means 'just use the + //! The joker value defined as @ref kwk::_ is used in various context to mean 'just use the //! most meaningful value'. //================================================================================================ inline constexpr joker _ = {}; From 6dfff49687e814bca1e682db84113d77422a3d8e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domagoj=20=C5=A0ari=C4=87?= Date: Wed, 19 Jul 2023 12:27:09 +0200 Subject: [PATCH 06/30] prefilled operator[] improvement attempts and quick-fixes: - was broken for 'partially dynamic' shapes? - did not 'exist' at all for fully static shapes - had duplicated const and nonconst code (with an extraneous assertion about mutating static values for the const version). empty_tuple is homogeneous? Minor stylistic fixes. --- include/kwk/detail/sequence/prefilled.hpp | 57 +++++++++++------------ 1 file changed, 28 insertions(+), 29 deletions(-) diff --git a/include/kwk/detail/sequence/prefilled.hpp b/include/kwk/detail/sequence/prefilled.hpp index 34158d65..00ef86fd 100644 --- a/include/kwk/detail/sequence/prefilled.hpp +++ b/include/kwk/detail/sequence/prefilled.hpp @@ -18,7 +18,7 @@ namespace kwk::__ { struct empty_tuple { - static constexpr bool is_homogeneous = false; + static constexpr bool is_homogeneous = true; constexpr auto operator==(empty_tuple const&) const noexcept { return true; } }; @@ -71,7 +71,7 @@ namespace kwk::__ static constexpr bool is_fully_explicit = (D.is_explicit && ... && true); // Do we have runtime storage for a given index ? - static constexpr auto contains(int i) { return setup.index[i] != -1; } + static constexpr auto contains(int i) { return setup.index[i] != -1; } // Default constructor KWK_TRIVIAL constexpr prefilled() noexcept : storage_type{} {} @@ -269,44 +269,29 @@ namespace kwk::__ } // Dynamic access - We rely on KUMI internals for speed and ease of detection - KWK_TRIVIAL constexpr auto operator[](std::convertible_to auto i) const noexcept - requires(is_dynamic && static_size>0) + KWK_TRIVIAL constexpr auto& operator[](std::convertible_to auto i) noexcept + requires(is_fully_dynamic && static_size>0) { - static_assert(is_homogeneous, "[KWK] - Dynamic axis access requires homogeneous extent types."); - auto const idx = static_cast(i); - - KIWAKU_ASSERT ( idx(i); KIWAKU_ASSERT ( contains(idx) , "[KWK] - Access at index " << idx << " overwrites a compile-time value of " << kumi::to_tuple(*this) ); - // KUMI internal shortcut - if constexpr(dynamic_size==1) return storage().impl.member0; - else return storage().impl.members[idx]; + return get(idx); } - KWK_TRIVIAL constexpr auto& operator[](std::convertible_to auto i) noexcept - requires(is_dynamic && static_size>0) + KWK_TRIVIAL constexpr auto operator[](std::convertible_to auto i) const noexcept + requires(is_fully_dynamic && static_size>0) { - static_assert(is_homogeneous, "[KWK] - Dynamic axis access requires homogeneous extent types."); - auto const idx = static_cast(i); - - KIWAKU_ASSERT ( idx(*this).get(static_cast(i)); + } - // KUMI internal shortcut - if constexpr(dynamic_size==1) return storage().impl.member0; - else return storage().impl.members[idx]; + KWK_TRIVIAL constexpr auto operator[](std::convertible_to auto i) const noexcept + requires(!(is_fully_dynamic && static_size>0)) + { + return as_array()[i]; // rely on std::array bounds checking } // Named access via Axis @@ -424,6 +409,20 @@ namespace kwk::__ KWK_TRIVIAL constexpr storage_type const& storage() const& { return static_cast(*this); } KWK_TRIVIAL constexpr storage_type && storage() && { return static_cast(*this); } KWK_TRIVIAL constexpr storage_type const&& storage() const&& { return static_cast(*this); } + + private: + constexpr auto& get(std::uint32_t const idx) noexcept + { + static_assert(is_homogeneous, "[KWK] - Dynamic axis access requires homogeneous extent types."); + + KIWAKU_ASSERT ( idx Date: Wed, 19 Jul 2023 12:29:44 +0200 Subject: [PATCH 07/30] Fixed coordinates() to use the correct underlying std::array type. --- include/kwk/utility/coordinates.hpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/include/kwk/utility/coordinates.hpp b/include/kwk/utility/coordinates.hpp index e46e2bd7..57db9059 100644 --- a/include/kwk/utility/coordinates.hpp +++ b/include/kwk/utility/coordinates.hpp @@ -25,12 +25,12 @@ namespace kwk //! //! @param idx Linear index to convert into a nD coordinate set //! @param shp Shape used as a reference - //! @return A std::array::value_type, shape::static_order> containing the + //! @return A std::array>, shape::static_order> containing the //! multi-dimensional position corresponding to idx //================================================================================================ - template + template KWK_CONST constexpr - auto coordinates( Idx idx, shape const shp) noexcept + auto coordinates( Idx const idx, shape const shp ) noexcept { KIWAKU_ASSERT ( idx < shp.numel() , "Converting index " << idx @@ -46,11 +46,12 @@ namespace kwk return [&](std::integer_sequence) { + using coord_t = typename __::largest_integral::type; auto const strides{as_stride(shp)}; - return std::array { static_cast( idx / get<0 >(strides) ) - , static_cast((idx / get(strides)) % get(shp))... + return std::array { static_cast( idx / get<0 >(strides) ) + , static_cast((idx / get(strides)) % get(shp))... }; - }(std::make_integer_sequence::static_order - 1 >{}); + }(std::make_integer_sequence::static_order - 1>{}); } } From c969e1dec20273461d3a61d62da7a2864a4c557d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domagoj=20=C5=A0ari=C4=87?= Date: Wed, 19 Jul 2023 12:32:04 +0200 Subject: [PATCH 08/30] Quick-hack fix for MB: we need default axis type to be 16 bits (a proper fix would be to make this configurable :grimace:). --- include/kwk/detail/sequence/helpers.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/kwk/detail/sequence/helpers.hpp b/include/kwk/detail/sequence/helpers.hpp index 215c29a5..ac1518b2 100644 --- a/include/kwk/detail/sequence/helpers.hpp +++ b/include/kwk/detail/sequence/helpers.hpp @@ -114,7 +114,7 @@ namespace kwk::__ // Type short-cut for internal representation of types in axis //==================================================================================================================== template struct stored_type : T {}; - template struct stored_type { using type = std::int32_t; }; + template struct stored_type { using type = std::uint16_t; }; template using stored_t = typename stored_type::type; From ac9cbb58a03f5b10dbd3ee4c9a912fa1d9f10489 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domagoj=20=C5=A0ari=C4=87?= Date: Wed, 19 Jul 2023 13:15:07 +0200 Subject: [PATCH 09/30] prefilled::get disambiguation. --- include/kwk/detail/sequence/prefilled.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/kwk/detail/sequence/prefilled.hpp b/include/kwk/detail/sequence/prefilled.hpp index 00ef86fd..a99cefb1 100644 --- a/include/kwk/detail/sequence/prefilled.hpp +++ b/include/kwk/detail/sequence/prefilled.hpp @@ -279,13 +279,13 @@ namespace kwk::__ << " overwrites a compile-time value of " << kumi::to_tuple(*this) ); - return get(idx); + return get_indexed( idx ); } KWK_TRIVIAL constexpr auto operator[](std::convertible_to auto i) const noexcept requires(is_fully_dynamic && static_size>0) { - return const_cast(*this).get(static_cast(i)); + return const_cast(*this).get_indexed(static_cast(i)); } KWK_TRIVIAL constexpr auto operator[](std::convertible_to auto i) const noexcept @@ -411,7 +411,7 @@ namespace kwk::__ KWK_TRIVIAL constexpr storage_type const&& storage() const&& { return static_cast(*this); } private: - constexpr auto& get(std::uint32_t const idx) noexcept + constexpr auto& get_indexed(std::uint32_t const idx) noexcept { static_assert(is_homogeneous, "[KWK] - Dynamic axis access requires homogeneous extent types."); From fb4f448c06dc17da1bbb4a8f354f8b7add7f8c41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domagoj=20=C5=A0ari=C4=87?= Date: Fri, 21 Jul 2023 09:30:36 +0200 Subject: [PATCH 10/30] Minor stylistic fixes. --- include/kwk/settings/type.hpp | 6 +++--- include/kwk/utility/container/shape.hpp | 4 ++-- include/kwk/utility/fixed.hpp | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/include/kwk/settings/type.hpp b/include/kwk/settings/type.hpp index dec14b1c..60f87a9c 100644 --- a/include/kwk/settings/type.hpp +++ b/include/kwk/settings/type.hpp @@ -79,11 +79,11 @@ namespace kwk constexpr inline auto uint8 = as; /// Pre-defined type settings for std::uint16_t - constexpr inline auto uint16= as; + constexpr inline auto uint16 = as; /// Pre-defined type settings for std::uint32_t - constexpr inline auto uint32= as; + constexpr inline auto uint32 = as; /// Pre-defined type settings for std::uint64_t - constexpr inline auto uint64= as; + constexpr inline auto uint64 = as; } diff --git a/include/kwk/utility/container/shape.hpp b/include/kwk/utility/container/shape.hpp index a309d2e5..0ba4f3ac 100644 --- a/include/kwk/utility/container/shape.hpp +++ b/include/kwk/utility/container/shape.hpp @@ -323,8 +323,8 @@ namespace kwk } // Access to base type for internal implementation - KWK_TRIVIAL constexpr auto const& __base() const noexcept { return static_cast(*this); } - KWK_TRIVIAL constexpr auto & __base() noexcept { return static_cast(*this); } + KWK_TRIVIAL constexpr auto const& __base() const noexcept { return static_cast(*this); } + KWK_TRIVIAL constexpr auto & __base() noexcept { return static_cast(*this); } }; /// Deduction guide for @ref kwk::shape diff --git a/include/kwk/utility/fixed.hpp b/include/kwk/utility/fixed.hpp index bcf9d161..cdc6a07d 100644 --- a/include/kwk/utility/fixed.hpp +++ b/include/kwk/utility/fixed.hpp @@ -61,7 +61,7 @@ namespace kwk template constexpr auto clamp() { - if constexpr (std::bit_width(Value) <= 8) return static_cast(Value); + if constexpr (std::bit_width(Value) <= 8) return static_cast(Value); else if constexpr (std::bit_width(Value) <= 19) return static_cast(Value); else if constexpr (std::bit_width(Value) <= 32) return static_cast(Value); else return Value; From 76f2aaef70360771dad04df2232df4671bb34e2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domagoj=20=C5=A0ari=C4=87?= Date: Sat, 22 Jul 2023 08:29:00 +0200 Subject: [PATCH 11/30] Hack-fix for compilation errors in coordinates() for shapes created with of_size() (which uses to_descriptor() - why?). --- include/kwk/utility/coordinates.hpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/include/kwk/utility/coordinates.hpp b/include/kwk/utility/coordinates.hpp index 57db9059..6070b540 100644 --- a/include/kwk/utility/coordinates.hpp +++ b/include/kwk/utility/coordinates.hpp @@ -17,6 +17,8 @@ namespace kwk { + namespace __ { template struct to_int> { using type = T; }; } + //================================================================================================ //! @ingroup utility //! @brief Computes a tuple of coordinates from a linear index and a shape @@ -30,7 +32,7 @@ namespace kwk //================================================================================================ template KWK_CONST constexpr - auto coordinates( Idx const idx, shape const shp ) noexcept + auto coordinates(Idx const idx, shape const shp) noexcept { KIWAKU_ASSERT ( idx < shp.numel() , "Converting index " << idx @@ -44,9 +46,9 @@ namespace kwk idx % shp[3], */ + using coord_t = typename __::largest_integral<__::to_int_t...>::type; return [&](std::integer_sequence) { - using coord_t = typename __::largest_integral::type; auto const strides{as_stride(shp)}; return std::array { static_cast( idx / get<0 >(strides) ) From 902560d28d1b6da7d8b45f627bb5b934329e5d7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domagoj=20=C5=A0ari=C4=87?= Date: Sat, 22 Jul 2023 08:31:37 +0200 Subject: [PATCH 12/30] axis_: - changed base_type to uint16 to match the (new) joker default (awaiting a proper solution) - added conversion operators to Content/value - attempt to make axis_ w/ empty Content an empty class. --- include/kwk/settings/axis.hpp | 10 ++++- test/utility/shape/default_ctor.cpp | 60 +++++++++++++++-------------- 2 files changed, 39 insertions(+), 31 deletions(-) diff --git a/include/kwk/settings/axis.hpp b/include/kwk/settings/axis.hpp index 240fa181..0c1b3bdd 100644 --- a/include/kwk/settings/axis.hpp +++ b/include/kwk/settings/axis.hpp @@ -27,7 +27,7 @@ namespace kwk::__ using is_product_type = void; using axis_kind = axis_; using content_type = Content; - using base_type = std::int32_t; + using base_type = std::uint16_t; using id_type = decltype(ID); static constexpr auto identifier = ID; @@ -103,7 +103,13 @@ namespace kwk::__ return axis_{v}; } - Content value = {}; + KWK_PURE explicit constexpr operator Content () const noexcept { return value; } + KWK_PURE constexpr Content operator*() const noexcept { return value; } + +#ifndef _WIN32 // https://github.com/llvm/llvm-project/issues/49358 Missing [[no_unique_address]] support on Windows + [[no_unique_address]] // allow empty axis_ for empty Content (e.g. joker) +#endif + Content value{}; }; template diff --git a/test/utility/shape/default_ctor.cpp b/test/utility/shape/default_ctor.cpp index 3d99c31d..9f88e60f 100644 --- a/test/utility/shape/default_ctor.cpp +++ b/test/utility/shape/default_ctor.cpp @@ -11,12 +11,14 @@ using kwk::_; +using axis_base_type = decltype(kwk::along<0>)::base_type; + TTS_CASE( "Default constructed shape behavior - Mixed 1D") { kwk::shape<_> shape_d; kwk::shape<7> shape_s; - TTS_EQUAL(sizeof(shape_d) ,1*sizeof(std::int32_t) ); + TTS_EQUAL(sizeof(shape_d) ,1*sizeof(axis_base_type)); TTS_EQUAL(sizeof(shape_s) , 1UL ); TTS_EQUAL(shape_d.nbdims() , 1 ); @@ -39,10 +41,10 @@ TTS_CASE( "Default constructed shape behavior - Mixed 2D") kwk::shape<7,_> shape_sd; kwk::shape<7,5> shape_ss; - TTS_EQUAL(sizeof(shape_dd), 2*sizeof(std::int32_t)); - TTS_EQUAL(sizeof(shape_ds), 1*sizeof(std::int32_t)); - TTS_EQUAL(sizeof(shape_sd), 1*sizeof(std::int32_t)); - TTS_EQUAL(sizeof(shape_ss), 1UL); + TTS_EQUAL(sizeof(shape_dd), 2*sizeof(axis_base_type)); + TTS_EQUAL(sizeof(shape_ds), 1*sizeof(axis_base_type)); + TTS_EQUAL(sizeof(shape_sd), 1*sizeof(axis_base_type)); + TTS_EQUAL(sizeof(shape_ss), 1UL); TTS_EQUAL(shape_dd.nbdims() , 2L); TTS_EQUAL(shape_ds.nbdims() , 2L); @@ -71,14 +73,14 @@ TTS_CASE( "Default constructed shape behavior - Mixed 3D") kwk::shape<7,5,_> shape_ssd; kwk::shape<7,5,3> shape_sss; - TTS_EQUAL(sizeof(shape_ddd) , 3*sizeof(std::int32_t)); - TTS_EQUAL(sizeof(shape_dds) , 2*sizeof(std::int32_t)); - TTS_EQUAL(sizeof(shape_dsd) , 2*sizeof(std::int32_t)); - TTS_EQUAL(sizeof(shape_dss) , 1*sizeof(std::int32_t)); - TTS_EQUAL(sizeof(shape_sdd) , 2*sizeof(std::int32_t)); - TTS_EQUAL(sizeof(shape_sds) , 1*sizeof(std::int32_t)); - TTS_EQUAL(sizeof(shape_ssd) , 1*sizeof(std::int32_t)); - TTS_EQUAL(sizeof(shape_sss) , 1UL); + TTS_EQUAL(sizeof(shape_ddd) , 3*sizeof(axis_base_type)); + TTS_EQUAL(sizeof(shape_dds) , 2*sizeof(axis_base_type)); + TTS_EQUAL(sizeof(shape_dsd) , 2*sizeof(axis_base_type)); + TTS_EQUAL(sizeof(shape_dss) , 1*sizeof(axis_base_type)); + TTS_EQUAL(sizeof(shape_sdd) , 2*sizeof(axis_base_type)); + TTS_EQUAL(sizeof(shape_sds) , 1*sizeof(axis_base_type)); + TTS_EQUAL(sizeof(shape_ssd) , 1*sizeof(axis_base_type)); + TTS_EQUAL(sizeof(shape_sss) , 1UL); TTS_EQUAL(shape_ddd.nbdims(), 3L); TTS_EQUAL(shape_dds.nbdims(), 3L); @@ -127,22 +129,22 @@ TTS_CASE( "Default constructed shape behavior - Mixed 4D") kwk::shape<9,7,5,_> shape_sssd; kwk::shape<9,7,5,3> shape_ssss; - TTS_EQUAL(sizeof(shape_dddd) , 4*sizeof(std::int32_t) ); - TTS_EQUAL(sizeof(shape_ddds) , 3*sizeof(std::int32_t) ); - TTS_EQUAL(sizeof(shape_ddsd) , 3*sizeof(std::int32_t) ); - TTS_EQUAL(sizeof(shape_ddss) , 2*sizeof(std::int32_t) ); - TTS_EQUAL(sizeof(shape_dsdd) , 3*sizeof(std::int32_t) ); - TTS_EQUAL(sizeof(shape_dsds) , 2*sizeof(std::int32_t) ); - TTS_EQUAL(sizeof(shape_dssd) , 2*sizeof(std::int32_t) ); - TTS_EQUAL(sizeof(shape_dsss) , 1*sizeof(std::int32_t) ); - TTS_EQUAL(sizeof(shape_sddd) , 3*sizeof(std::int32_t) ); - TTS_EQUAL(sizeof(shape_sdds) , 2*sizeof(std::int32_t) ); - TTS_EQUAL(sizeof(shape_sdsd) , 2*sizeof(std::int32_t) ); - TTS_EQUAL(sizeof(shape_sdss) , 1*sizeof(std::int32_t) ); - TTS_EQUAL(sizeof(shape_ssdd) , 2*sizeof(std::int32_t) ); - TTS_EQUAL(sizeof(shape_ssds) , 1*sizeof(std::int32_t) ); - TTS_EQUAL(sizeof(shape_sssd) , 1*sizeof(std::int32_t) ); - TTS_EQUAL(sizeof(shape_ssss) , 1UL ); + TTS_EQUAL(sizeof(shape_dddd) , 4*sizeof(axis_base_type) ); + TTS_EQUAL(sizeof(shape_ddds) , 3*sizeof(axis_base_type) ); + TTS_EQUAL(sizeof(shape_ddsd) , 3*sizeof(axis_base_type) ); + TTS_EQUAL(sizeof(shape_ddss) , 2*sizeof(axis_base_type) ); + TTS_EQUAL(sizeof(shape_dsdd) , 3*sizeof(axis_base_type) ); + TTS_EQUAL(sizeof(shape_dsds) , 2*sizeof(axis_base_type) ); + TTS_EQUAL(sizeof(shape_dssd) , 2*sizeof(axis_base_type) ); + TTS_EQUAL(sizeof(shape_dsss) , 1*sizeof(axis_base_type) ); + TTS_EQUAL(sizeof(shape_sddd) , 3*sizeof(axis_base_type) ); + TTS_EQUAL(sizeof(shape_sdds) , 2*sizeof(axis_base_type) ); + TTS_EQUAL(sizeof(shape_sdsd) , 2*sizeof(axis_base_type) ); + TTS_EQUAL(sizeof(shape_sdss) , 1*sizeof(axis_base_type) ); + TTS_EQUAL(sizeof(shape_ssdd) , 2*sizeof(axis_base_type) ); + TTS_EQUAL(sizeof(shape_ssds) , 1*sizeof(axis_base_type) ); + TTS_EQUAL(sizeof(shape_sssd) , 1*sizeof(axis_base_type) ); + TTS_EQUAL(sizeof(shape_ssss) , 1UL ); TTS_EQUAL(shape_dddd.nbdims(), 4L); TTS_EQUAL(shape_ddds.nbdims(), 4L); From 85af75ce7b60f75dad004a5679f3b85bfbc2ca88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domagoj=20=C5=A0ari=C4=87?= Date: Sat, 22 Jul 2023 09:04:26 +0200 Subject: [PATCH 13/30] Fixed warning-as-error on non-Clang compilers. --- include/kwk/utility/container/shape.hpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/include/kwk/utility/container/shape.hpp b/include/kwk/utility/container/shape.hpp index 0ba4f3ac..4a808639 100644 --- a/include/kwk/utility/container/shape.hpp +++ b/include/kwk/utility/container/shape.hpp @@ -74,7 +74,11 @@ namespace kwk //! @tparam D List of @ref glossary-extent types //==================================================================================================================== template - struct [[ clang::trivial_abi ]] shape : __::prefilled_t::type + struct +#ifdef __clang__ + [[clang::trivial_abi]] +#endif + shape : __::prefilled_t::type { using parent = typename __::prefilled_t::type; using constraint_t = KWK_DEFAULT_SHAPE_CONSTRAINTS; From 686e17703ee03c988309f8f35c1a6e1b01eceb53 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domagoj=20=C5=A0ari=C4=87?= Date: Thu, 3 Aug 2023 13:09:49 +0200 Subject: [PATCH 14/30] Fixed as_dimension for axis. --- include/kwk/utility/traits/as_dimension.hpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/include/kwk/utility/traits/as_dimension.hpp b/include/kwk/utility/traits/as_dimension.hpp index 96c8eb2c..44ceac82 100644 --- a/include/kwk/utility/traits/as_dimension.hpp +++ b/include/kwk/utility/traits/as_dimension.hpp @@ -68,9 +68,9 @@ namespace kwk namespace kwk::__ { - KWK_TRIVIAL constexpr auto as_dimension_(KWK_DELAY(), joker , std::integral auto d) { return d; } - KWK_TRIVIAL constexpr auto as_dimension_(KWK_DELAY(), concepts::axis auto , std::integral auto d) { return d; } - KWK_TRIVIAL constexpr auto as_dimension_(KWK_DELAY(), std::integral auto v, std::integral auto ) { return v; } + KWK_TRIVIAL constexpr auto as_dimension_(KWK_DELAY(), joker , std::integral auto d) { return d; } + KWK_TRIVIAL constexpr auto as_dimension_(KWK_DELAY(), concepts::axis auto v, std::integral auto ) { return v.value; } + KWK_TRIVIAL constexpr auto as_dimension_(KWK_DELAY(), std::integral auto v, std::integral auto ) { return v; } KWK_TRIVIAL constexpr auto as_dimension_(KWK_DELAY(), concepts::static_constant auto a, std::integral auto) { From 1e7676482d8c5ce1a8e1950681fa500dca56b6ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domagoj=20=C5=A0ari=C4=87?= Date: Thu, 3 Aug 2023 13:30:30 +0200 Subject: [PATCH 15/30] Add operator== to tuple [to enable easier and simpler equivalents in (kwk) wrappers]. --- include/kwk/detail/kumi.hpp | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/include/kwk/detail/kumi.hpp b/include/kwk/detail/kumi.hpp index 0d1aa117..0d35d118 100644 --- a/include/kwk/detail/kumi.hpp +++ b/include/kwk/detail/kumi.hpp @@ -71,6 +71,7 @@ namespace kumi::_ { static constexpr bool is_homogeneous = true; T0 members[N]; + constexpr bool operator==(binder_n const & other) const noexcept = default; }; template requires(all_the_same && no_references) @@ -106,6 +107,7 @@ namespace kumi::_ using kumi_specific_layout = void; using member0_type = T; member0_type member0; + constexpr bool operator==(binder const & other) const noexcept = default; }; template requires(no_references) @@ -117,6 +119,7 @@ namespace kumi::_ using member1_type = T1; member0_type member0; member1_type member1; + constexpr bool operator==(binder const & other) const noexcept = default; }; template requires(no_references) @@ -130,6 +133,7 @@ namespace kumi::_ member0_type member0; member1_type member1; member2_type member2; + constexpr bool operator==(binder const & other) const noexcept = default; }; template requires(no_references) @@ -145,6 +149,7 @@ namespace kumi::_ member1_type member1; member2_type member2; member3_type member3; + constexpr bool operator==(binder const & other) const noexcept = default; }; template requires(no_references) @@ -162,6 +167,7 @@ namespace kumi::_ member2_type member2; member3_type member3; member4_type member4; + constexpr bool operator==(binder const & other) const noexcept = default; }; template requires(no_references) @@ -181,6 +187,7 @@ namespace kumi::_ member3_type member3; member4_type member4; member5_type member5; + constexpr bool operator==(binder const & other) const noexcept = default; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6 @@ -204,6 +211,7 @@ namespace kumi::_ member4_type member4; member5_type member5; member6_type member6; + constexpr bool operator==(binder const & other) const noexcept = default; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7 @@ -229,6 +237,7 @@ namespace kumi::_ member5_type member5; member6_type member6; member7_type member7; + constexpr bool operator==(binder const & other) const noexcept = default; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8 @@ -256,6 +265,7 @@ namespace kumi::_ member6_type member6; member7_type member7; member8_type member8; + constexpr bool operator==(binder const & other) const noexcept = default; }; template< typename T0, typename T1, typename T2, typename T3, typename T4 , typename T5, typename T6, typename T7, typename T8, typename T9 @@ -285,6 +295,7 @@ namespace kumi::_ member7_type member7; member8_type member8; member9_type member9; + constexpr bool operator==(binder const & other) const noexcept = default; }; template requires requires(Binder) { typename Binder::kumi_specific_layout; } @@ -659,6 +670,7 @@ namespace kumi (std::make_index_sequence()); return *this; } + constexpr bool operator==(tuple const & other) const noexcept = default; template friend constexpr auto operator==(tuple const &self, tuple const &other) noexcept requires( (sizeof...(Ts) == sizeof...(Us) ) && equality_comparable> ) From 87ad84236d6cbfce37d45fb75e0e1e2f5e285f46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domagoj=20=C5=A0ari=C4=87?= Date: Thu, 3 Aug 2023 13:46:22 +0200 Subject: [PATCH 16/30] Ad-hoc ability to configure underlying joker integral type (its size). Fixed map_descriptor to support/detect static_constants as static axes. Changed fixed<> to prevent recursive constant>s. --- include/kwk/detail/sequence/helpers.hpp | 11 +++++----- include/kwk/utility/fixed.hpp | 26 ++++++++++------------ include/kwk/utility/joker.hpp | 29 +++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 19 deletions(-) diff --git a/include/kwk/detail/sequence/helpers.hpp b/include/kwk/detail/sequence/helpers.hpp index ac1518b2..5de532f2 100644 --- a/include/kwk/detail/sequence/helpers.hpp +++ b/include/kwk/detail/sequence/helpers.hpp @@ -9,6 +9,7 @@ #include #include +#include #include #include #include @@ -34,7 +35,7 @@ namespace kwk::__ // Check if the current extent descriptor is an integer (ie a static size) or not auto check = [&](T) { - if constexpr(std::integral) index[pos] = -1; + if constexpr(std::integral || concepts::static_constant) index[pos] = -1; else { stored[stored_pos++] = pos; @@ -113,9 +114,9 @@ namespace kwk::__ //==================================================================================================================== // Type short-cut for internal representation of types in axis //==================================================================================================================== - template struct stored_type : T {}; - template struct stored_type { using type = std::uint16_t; }; + template struct stored_type : T {}; + template struct stored_type { using type = joker::value_type(descriptors).value.integral_value_type_size>; }; - template - using stored_t = typename stored_type::type; + template + using stored_t = typename stored_type::type; } diff --git a/include/kwk/utility/fixed.hpp b/include/kwk/utility/fixed.hpp index cdc6a07d..6c2caaa8 100644 --- a/include/kwk/utility/fixed.hpp +++ b/include/kwk/utility/fixed.hpp @@ -27,20 +27,12 @@ namespace kwk namespace __ { - template struct to_int { using type = T; }; - template<> struct to_int { using type = char; }; + template struct to_int { using type = T; }; + template<> struct to_int { using type = joker::value_type<>; }; - template - struct to_int - { - using type = typename T::stored_value_type; - }; - - template - struct to_int - { - using type = typename T::value_type; - }; + template struct to_int { using type = typename T::stored_value_type; }; + template struct to_int { using type = typename T::value_type ; }; + template struct to_int { using type = typename T::content_type ; }; template using to_int_t = typename to_int::type; @@ -97,7 +89,13 @@ namespace kwk //! @brief Provides a short-cut to define a `std::integral_constant` value from a literal integer //================================================================================================ template - inline constexpr auto fixed = constant{}; + inline constexpr auto fixed = []() + { + if constexpr(concepts::static_constant) // prevent recursive constant> + return N; + else + return constant{}; + }(); inline namespace literals { diff --git a/include/kwk/utility/joker.hpp b/include/kwk/utility/joker.hpp index 8a2b7fe8..7c94c701 100644 --- a/include/kwk/utility/joker.hpp +++ b/include/kwk/utility/joker.hpp @@ -8,10 +8,27 @@ #pragma once #include +#include #include +#ifndef KWK_DEFAULT_AXIS_BITNESS +#define KWK_DEFAULT_AXIS_BITNESS -32 +#endif + namespace kwk { + namespace detail + { + template struct int_type; + template <> struct int_type< 8> { using type = std:: int8_t; }; + template <> struct int_type<16> { using type = std::int16_t; }; + template <> struct int_type<32> { using type = std::int32_t; }; + template <> struct int_type<64> { using type = std::int64_t; }; + + template struct as_signed { using type = std::make_unsigned_t; }; + template < typename T> struct as_signed { using type = std:: make_signed_t; }; + } + //================================================================================================ //! @ingroup utility //! @brief Type of the @ref kwk::_ object @@ -27,6 +44,18 @@ namespace kwk KWK_TRIVIAL friend constexpr joker operator*(joker, joker) noexcept { return {}; } KWK_TRIVIAL friend constexpr joker operator*(joker, auto) noexcept { return {}; } KWK_TRIVIAL friend constexpr joker operator*(auto , joker) noexcept { return {}; } + + std::int8_t integral_value_type_size = KWK_DEFAULT_AXIS_BITNESS; + + template + constexpr joker operator[](Integral /*const v*/) const noexcept { /*ct_assert(v == 0)*/ return { std::int8_t(sizeof(Integral)) * (std::is_signed_v ? -8 : 8 )}; } + + template + using value_type = typename detail::as_signed + < + bitness < 0, + typename detail::int_type::type + >::type; }; //================================================================================================ From 5bc8bf7df89b9701f368189f82355f50a5a15bd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domagoj=20=C5=A0ari=C4=87?= Date: Thu, 3 Aug 2023 13:49:00 +0200 Subject: [PATCH 17/30] 'Fixed' KWK_DEFAULT_SHAPE_CONSTRAINTS support by adding the accompanying KWK_DEFAULT_SHAPE_CONSTRAINTS_INCLUDE. --- include/kwk/detail/sequence/shape_constraints.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/kwk/detail/sequence/shape_constraints.hpp b/include/kwk/detail/sequence/shape_constraints.hpp index 6d2fd3aa..c93dcf8f 100644 --- a/include/kwk/detail/sequence/shape_constraints.hpp +++ b/include/kwk/detail/sequence/shape_constraints.hpp @@ -12,6 +12,8 @@ #if !defined(KWK_DEFAULT_SHAPE_CONSTRAINTS) #define KWK_DEFAULT_SHAPE_CONSTRAINTS ::kwk::basic_shape_checks +#elif defined(KWK_DEFAULT_SHAPE_CONSTRAINTS_INCLUDE) +#include KWK_DEFAULT_SHAPE_CONSTRAINTS_INCLUDE #endif namespace kwk From 6351533d45636879abdb94d4c25b1299df92ce1b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domagoj=20=C5=A0ari=C4=87?= Date: Thu, 3 Aug 2023 14:02:37 +0200 Subject: [PATCH 18/30] Updated with joker changes. Added is_untyped and is_fully_typed attributes to prefilled. Added several shortcut implementations for is_fully_dynamic cases. Changed const prefilled<>::operator[] to return a 'typed axis' value. Changed/split/expanded prefilled<>::axis() to: axis_kind, axis_at, axis and axis_with_extent (preferring variable templates instead of functions). Fixed axis_::is_dynamic to support/handle static_constants. Added extent() as a thin alternative to as_dimension. Minor stylistic changes. --- include/kwk/detail/sequence/prefilled.hpp | 148 ++++++++++++++++------ include/kwk/settings/axis.hpp | 33 ++++- include/kwk/utility/container/stride.hpp | 4 +- 3 files changed, 139 insertions(+), 46 deletions(-) diff --git a/include/kwk/detail/sequence/prefilled.hpp b/include/kwk/detail/sequence/prefilled.hpp index a99cefb1..65fc4d38 100644 --- a/include/kwk/detail/sequence/prefilled.hpp +++ b/include/kwk/detail/sequence/prefilled.hpp @@ -22,6 +22,22 @@ namespace kwk::__ constexpr auto operator==(empty_tuple const&) const noexcept { return true; } }; + // TODO: move to kumi + template + using type_pack_element = +#ifdef __clang__ + __type_pack_element; +#else + kumi::element_t>; +#endif + template + using type_nttp_pack_element = type_pack_element; + + template constexpr auto axis_as_unit_aux { an_axis }; + template constexpr auto axis_as_unit_aux{ an_axis.value }; // indexed axes have no 'units'/are dimensionless/plain numbers + + template constexpr auto axis_as_unit{ axis_as_unit_aux }; + template struct prefilled_base { @@ -39,8 +55,16 @@ namespace kwk::__ { return [&](std::index_sequence) { - using base = decltype(kumi::make_tuple(D...)); - return kumi::tuple>... >{}; + return kumi::tuple + < + stored_t + < + type_nttp_pack_element, + setup.stored[N], + descriptors + > + ... + >{}; }(std::make_index_sequence{}); } } @@ -67,8 +91,10 @@ namespace kwk::__ static constexpr bool is_dynamic = !is_fully_static; static constexpr bool is_fully_dynamic = dynamic_size == static_size; static constexpr bool is_homogeneous = storage_type::is_homogeneous; - static constexpr bool is_fully_implicit = (D.is_implicit && ... && true); - static constexpr bool is_fully_explicit = (D.is_explicit && ... && true); + static constexpr bool is_fully_implicit = ( D.is_implicit && ... && true); + static constexpr bool is_fully_explicit = ( D.is_explicit && ... && true); + static constexpr bool is_untyped = ( D.is_indexed && ... && true); + static constexpr bool is_fully_typed = (!D.is_indexed && ... && true); // Do we have runtime storage for a given index ? static constexpr auto contains(int i) { return setup.index[i] != -1; } @@ -80,24 +106,31 @@ namespace kwk::__ constexpr void __construct(auto def, concepts::numeric_extent auto... vs) noexcept { - auto const input = kumi::tie(vs...); - kumi::for_each_index( [&](I, auto v) - { - if constexpr(contains(I::value)) - { - __get() = kwk::as_dimension(v, def); - } - else + if constexpr(is_fully_dynamic) + { + static_cast(*this) = storage_type{/*extent(vs)*/kwk::as_dimension(vs, def)...}; + } + else + { + auto const input = kumi::tie(vs...); + kumi::for_each_index( [&](I, auto v) { - KIWAKU_ASSERT ( (v == _) || v == __get() - , "[KWK] - Runtime/Compile-time mismatch for axis " - << kumi::get(descriptors) << " as " - << v << " was provided instead." - ); + if constexpr(contains(I::value)) + { + __get() = kwk::as_dimension(v, def); + } + else + { + KIWAKU_ASSERT ( (v == _) || v == __get() + , "[KWK] - Runtime/Compile-time mismatch for axis " + << kumi::get(descriptors) << " as " + << v << " was provided instead." + ); + } } - } - , input - ); + , input + ); + } } constexpr void __construct(auto def, concepts::named_extent auto... vs) noexcept @@ -163,7 +196,7 @@ namespace kwk::__ auto ff = [](constant, X) { if constexpr(rbr::concepts::option) return typename X::keyword_type{}; - else return implicit; + else return implicit; }; return [&](std::index_sequence) @@ -203,13 +236,6 @@ namespace kwk::__ ); } - // Static axis access - template - KWK_TRIVIAL constexpr auto axis() const noexcept - { - return get(descriptors).base(); - } - // Static tuple access impl template KWK_TRIVIAL constexpr decltype(auto) __get() const & noexcept @@ -279,7 +305,7 @@ namespace kwk::__ << " overwrites a compile-time value of " << kumi::to_tuple(*this) ); - return get_indexed( idx ); + return get_indexed(idx); } KWK_TRIVIAL constexpr auto operator[](std::convertible_to auto i) const noexcept @@ -302,10 +328,10 @@ namespace kwk::__ } template - KWK_TRIVIAL constexpr decltype(auto) operator[](A) const noexcept + KWK_TRIVIAL constexpr decltype(auto) operator[](A const a) const noexcept requires(__find_axis(A{}) < static_size) { - return __get<__find_axis(A{})>(); + return a[__get<__find_axis(A{})>()]; // return a 'typed axis' wrapper of the raw value (at least for the non mutable case) } template @@ -319,13 +345,35 @@ namespace kwk::__ // If an error occurs here, this means you tried to access a shape/stride value by an axis // descriptor which is not contained in said shape/stride. // E.g: - // kwk::shape< width * height > x; + // kwk::shape< width, height > x; // x[depth] = 4; //================================================================================================================== template requires(__find_axis(A{}) >= static_size) constexpr auto operator[](A) const noexcept = delete; + + // Static axis access + template + using axis_kind = typename type_nttp_pack_element::axis_kind; + + template + static constexpr auto axis_at{__::axis_as_unit(descriptors)>}; + + template + static constexpr auto axis{axis_at<__find_axis(AxisID)>}; + + template + static constexpr auto axis_with_extent(auto const value) noexcept + { + auto const the_axis{get(descriptors)}; + if constexpr(the_axis.is_indexed) + return value; + else + return the_axis[value]; + } + + // Total size of the tuple static constexpr std::int32_t size() noexcept { return static_size; } @@ -341,13 +389,31 @@ namespace kwk::__ // Conversion to std::array constexpr decltype(auto) as_array() const noexcept { - return kumi::apply( [](T... m) - { - using type = typename largest_integral::type; - return std::array{static_cast(m)...}; - } - , *this - ); + if constexpr(is_homogeneous && is_fully_dynamic) + { + if constexpr(dynamic_size==0) return std::array, 0>{}; + else if constexpr(dynamic_size==1) return std::array{storage().impl.member0}; + else + return reinterpret_cast + < + std::array + < + std::tuple_element_t<0, storage_type>, + dynamic_size + > const & + > + (storage().impl.members); + } + else + { + return kumi::apply( [](T... m) + { + using type = typename largest_integral::type; + return std::array{static_cast(m)...}; + } + , *this + ); + } } // Equivalence checks for same order/axis kind @@ -358,7 +424,7 @@ namespace kwk::__ else return false; } - // Compatiblity checks if they have the same size and don't contain conflicting static values + // Compatiblity checks if they have the same size and don't contain conflicting static values template constexpr bool is_compatible(prefilled const& other) const noexcept { @@ -437,7 +503,7 @@ namespace kwk::__ { return [](std::index_sequence) { - return kwk::__::box< prefilled(normalized)...> >{}; + return kwk::__::box(normalized)...>>{}; }(std::make_index_sequence{}); } diff --git a/include/kwk/settings/axis.hpp b/include/kwk/settings/axis.hpp index 0c1b3bdd..5dbd8ad2 100644 --- a/include/kwk/settings/axis.hpp +++ b/include/kwk/settings/axis.hpp @@ -8,7 +8,9 @@ #pragma once #include +#include #include +#include #include #include #include @@ -27,15 +29,16 @@ namespace kwk::__ using is_product_type = void; using axis_kind = axis_; using content_type = Content; - using base_type = std::uint16_t; + using base_type = joker::value_type<>; using id_type = decltype(ID); static constexpr auto identifier = ID; - static constexpr bool is_dynamic = !std::integral; + static constexpr bool is_joker = std::is_same_v; + static constexpr bool is_dynamic = !std::integral && !concepts::static_constant; static constexpr bool is_indexed = std::integral; static constexpr bool is_implicit = []() { - if constexpr(std::integral) return ID < 0; else return false; + if constexpr(is_indexed) return ID < 0; else return false; }(); static constexpr bool is_explicit = !is_implicit; @@ -103,6 +106,10 @@ namespace kwk::__ return axis_{v}; } + template + KWK_PURE constexpr bool operator ==(T const v) const noexcept requires(!concepts::axis) { return value == v; } + KWK_PURE constexpr bool operator ==(joker ) const noexcept { return std::same_as; } + KWK_PURE explicit constexpr operator Content () const noexcept { return value; } KWK_PURE constexpr Content operator*() const noexcept { return value; } @@ -148,4 +155,24 @@ namespace kwk /// Predefined axis for channel inline constexpr auto channel = axis<"channel">; + + // thin as_dimension + constexpr auto extent(std::integral auto const dim) noexcept { return dim; } + constexpr auto extent(concepts::axis auto const dim) noexcept { return dim.value; } + constexpr auto extent(concepts::static_constant auto const dim) noexcept { return dim; } + inline constexpr auto extent(joker ) noexcept { return joker::value_type<>{0}; } // use zero as a numeric (compile time) value to represent dynamic/runtime axes? + + constexpr auto axis_with_extent(concepts::axis auto const axis, auto const extent) noexcept { return axis [extent]; } + constexpr auto axis_with_extent(std::integral auto const axis, auto const extent) noexcept { return decltype(axis){extent}; } + constexpr auto axis_with_extent(std::integral auto , joker const extent) noexcept { return extent ; } + constexpr auto axis_with_extent(joker , auto const extent) noexcept { return extent ; } + constexpr auto axis_with_extent(concepts::static_constant auto const axis, auto const extent) noexcept + { + KIWAKU_ASSERT(extent == axis, "Static axis and extent size mismatch"); +#ifdef __clang__ + __builtin_assume(extent == axis.value); +#endif + return axis; + } + constexpr auto axis_with_extent(concepts::axis auto const axis, concepts::axis auto const extent) noexcept { return axis [extent.value]; } } diff --git a/include/kwk/utility/container/stride.hpp b/include/kwk/utility/container/stride.hpp index 5125f62e..e9cd97aa 100644 --- a/include/kwk/utility/container/stride.hpp +++ b/include/kwk/utility/container/stride.hpp @@ -121,7 +121,7 @@ namespace kwk template KWK_PURE constexpr auto as_stride(shape s) noexcept { - if constexpr(sizeof...(D) == 1) return stride{s.template axis<0>() = fixed<1>}; + if constexpr(sizeof...(D) == 1) return stride{s.template axis_with_extent<0>(fixed<1>)}; else { auto const d = kumi::fold_left ( [](auto a, auto m){ return push_front(a, m * front(a)); } @@ -131,7 +131,7 @@ namespace kwk return [&](std::index_sequence, auto t) { - return stride{ (s.template axis() = get(t))... }; + return stride{ (s.template axis_with_extent(get(t)))... }; }(std::make_index_sequence{}, d); } } From 68d2c50496609b65058a27345b94ae371cca0733 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domagoj=20=C5=A0ari=C4=87?= Date: Thu, 3 Aug 2023 14:09:56 +0200 Subject: [PATCH 19/30] Added static_axes and static_values 'accessors' to shape (should probably moved to the enclosing namespace). Changed the shape(...) constructor to be explicit only for single-dim shapes (not necessary otherwise?). Similarily for differently sized conversion constructor: explicit only if requiring 'compression' (as that isn't obviously the behaviour everyone would want). Added a simple/direct operator== overload. --- include/kwk/utility/container/shape.hpp | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/include/kwk/utility/container/shape.hpp b/include/kwk/utility/container/shape.hpp index 4a808639..4963552d 100644 --- a/include/kwk/utility/container/shape.hpp +++ b/include/kwk/utility/container/shape.hpp @@ -102,7 +102,10 @@ namespace kwk /// Indicates that the shape's dimensions are all specified compile-time static constexpr bool is_fully_static = parent::is_fully_static; - // shape is its self option keyword + static constexpr auto static_axes = kumi::tuple{ D ...}; + static constexpr auto static_values = kumi::tuple{extent(D)...}; + + // shape is itself an option keyword using stored_value_type = shape; using keyword_type = __::size_; @@ -174,8 +177,8 @@ namespace kwk //! @param d Variadic list of @ref glossary-extent. //================================================================================================================== template - requires( std::is_constructible_v ) - KWK_TRIVIAL explicit constexpr shape(T... d) noexcept : parent(0, d...) {} + requires(std::is_constructible_v) + KWK_TRIVIAL explicit(sizeof...(T) == 1) constexpr shape(T... d) noexcept : parent(joker::value_type<>{0}, d...) {} //================================================================================================================== /// Copy constructor @@ -188,14 +191,14 @@ namespace kwk //! //! Copy the content of another kwk::shape if their extents and axis are compatible. //! - //! @note This constructor is explicit if the order of current shape is not equal to the order of `other`. + //! @note This constructor is explicit if the order of current shape is less than the order of `other` (thus requiring 'compression'). //! @param other Shape to copy //================================================================================================================== template requires( constraint_t::is_contructible_from::parent{}>() ) KWK_TRIVIAL #if !defined(KWK_DOXYGEN_INVOKED) - explicit(static_order != sizeof...(D2)) + explicit(static_order < sizeof...(D2)) #endif constexpr shape(shape const& other) noexcept { @@ -220,6 +223,11 @@ namespace kwk } /// Equality comparison operator + KWK_PURE friend constexpr bool operator==(shape const& a, shape const& b) noexcept + { + return a.storage() == b.storage(); + } + template KWK_PURE friend constexpr bool operator==(shape const& a, shape const& b) noexcept { From d27c852bb13673eb2f1d44e54e47b4d103ffe841 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domagoj=20=C5=A0ari=C4=87?= Date: Thu, 3 Aug 2023 16:37:31 +0200 Subject: [PATCH 20/30] New shiny CMake objects. --- cmake/make_unit.cmake | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/cmake/make_unit.cmake b/cmake/make_unit.cmake index b775ce31..42ac5ceb 100644 --- a/cmake/make_unit.cmake +++ b/cmake/make_unit.cmake @@ -10,10 +10,14 @@ include(add_target_parent) ##================================================================================================== add_library(kiwaku_test INTERFACE) -if(MSVC) +if(CMAKE_CXX_COMPILER_ID MATCHES "Clang") + if(CMAKE_CXX_COMPILER_FRONTEND_VARIANT STREQUAL "MSVC") + target_compile_options( kiwaku_test INTERFACE /W3 /EHsc /bigobj /std:c++20 ) + else() + target_compile_options( kiwaku_test INTERFACE -std=c++20 -Werror -Wall -Wextra -Wconversion -Wunused-variable -Wdocumentation) + endif() +elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") target_compile_options( kiwaku_test INTERFACE /W3 /EHsc /bigobj /std:c++20) -elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang") - target_compile_options( kiwaku_test INTERFACE -std=c++20 -Werror -Wall -Wextra -Wconversion -Wunused-variable -Wdocumentation) else() target_compile_options( kiwaku_test INTERFACE -std=c++20 -Werror -Wall -Wextra -Wconversion -Wunused-variable) endif() From c358a4c484b520f1ff96b2b5c55392c10edce142 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domagoj=20=C5=A0ari=C4=87?= Date: Thu, 3 Aug 2023 17:02:21 +0200 Subject: [PATCH 21/30] Replaced the configurable-joker-underlying-type ugliness with a simple/static preprocessor based configuration point (use as<> otherwise). Protected __type_pack_element usage with a has_builtin check. Moved main/basic extent() functions to the extent.hpp header. Removed no longer needed base_type and is_joker axis_ members. Optimized fixed and axis_::is_implicit not to invoke CT function. --- include/kwk/detail/sequence/helpers.hpp | 8 ++--- include/kwk/detail/sequence/prefilled.hpp | 19 ++++-------- include/kwk/settings/axis.hpp | 18 ++++-------- include/kwk/settings/type.hpp | 4 ++- include/kwk/utility/container/shape.hpp | 3 +- include/kwk/utility/fixed.hpp | 15 ++++------ include/kwk/utility/joker.hpp | 36 +++++++---------------- include/kwk/utility/traits/extent.hpp | 8 +++++ 8 files changed, 44 insertions(+), 67 deletions(-) diff --git a/include/kwk/detail/sequence/helpers.hpp b/include/kwk/detail/sequence/helpers.hpp index 5de532f2..5ccc6815 100644 --- a/include/kwk/detail/sequence/helpers.hpp +++ b/include/kwk/detail/sequence/helpers.hpp @@ -114,9 +114,9 @@ namespace kwk::__ //==================================================================================================================== // Type short-cut for internal representation of types in axis //==================================================================================================================== - template struct stored_type : T {}; - template struct stored_type { using type = joker::value_type(descriptors).value.integral_value_type_size>; }; + template struct stored_type : T {}; + template struct stored_type { using type = joker::default_type; }; - template - using stored_t = typename stored_type::type; + template + using stored_t = typename stored_type::type; } diff --git a/include/kwk/detail/sequence/prefilled.hpp b/include/kwk/detail/sequence/prefilled.hpp index 65fc4d38..d8e60a90 100644 --- a/include/kwk/detail/sequence/prefilled.hpp +++ b/include/kwk/detail/sequence/prefilled.hpp @@ -13,6 +13,7 @@ #include #include #include +#include namespace kwk::__ { @@ -25,7 +26,7 @@ namespace kwk::__ // TODO: move to kumi template using type_pack_element = -#ifdef __clang__ +#if defined(__clang__) && __has_builtin(__type_pack_element) __type_pack_element; #else kumi::element_t>; @@ -55,16 +56,7 @@ namespace kwk::__ { return [&](std::index_sequence) { - return kumi::tuple - < - stored_t - < - type_nttp_pack_element, - setup.stored[N], - descriptors - > - ... - >{}; + return kumi::tuple>...>{}; }(std::make_index_sequence{}); } } @@ -108,7 +100,8 @@ namespace kwk::__ { if constexpr(is_fully_dynamic) { - static_cast(*this) = storage_type{/*extent(vs)*/kwk::as_dimension(vs, def)...}; + using kwk::extent; + static_cast(*this) = storage_type{extent(vs)...}; } else { @@ -391,7 +384,7 @@ namespace kwk::__ { if constexpr(is_homogeneous && is_fully_dynamic) { - if constexpr(dynamic_size==0) return std::array, 0>{}; + if constexpr(dynamic_size==0) return std::array{}; else if constexpr(dynamic_size==1) return std::array{storage().impl.member0}; else return reinterpret_cast diff --git a/include/kwk/settings/axis.hpp b/include/kwk/settings/axis.hpp index 5dbd8ad2..2eb2bb99 100644 --- a/include/kwk/settings/axis.hpp +++ b/include/kwk/settings/axis.hpp @@ -22,6 +22,9 @@ namespace kwk { struct joker; } namespace kwk::__ { + template constexpr bool is_implicit { false }; + template constexpr bool is_implicit{ ID < 0 }; + // Axis descriptor with an ID template struct axis_ : rbr::as_keyword> @@ -29,18 +32,12 @@ namespace kwk::__ using is_product_type = void; using axis_kind = axis_; using content_type = Content; - using base_type = joker::value_type<>; using id_type = decltype(ID); static constexpr auto identifier = ID; - static constexpr bool is_joker = std::is_same_v; static constexpr bool is_dynamic = !std::integral && !concepts::static_constant; static constexpr bool is_indexed = std::integral; - static constexpr bool is_implicit = []() - { - if constexpr(is_indexed) return ID < 0; else return false; - }(); - + static constexpr bool is_implicit = __::is_implicit; static constexpr bool is_explicit = !is_implicit; // Equivalence @@ -156,11 +153,6 @@ namespace kwk /// Predefined axis for channel inline constexpr auto channel = axis<"channel">; - // thin as_dimension - constexpr auto extent(std::integral auto const dim) noexcept { return dim; } - constexpr auto extent(concepts::axis auto const dim) noexcept { return dim.value; } - constexpr auto extent(concepts::static_constant auto const dim) noexcept { return dim; } - inline constexpr auto extent(joker ) noexcept { return joker::value_type<>{0}; } // use zero as a numeric (compile time) value to represent dynamic/runtime axes? constexpr auto axis_with_extent(concepts::axis auto const axis, auto const extent) noexcept { return axis [extent]; } constexpr auto axis_with_extent(std::integral auto const axis, auto const extent) noexcept { return decltype(axis){extent}; } @@ -174,5 +166,5 @@ namespace kwk #endif return axis; } - constexpr auto axis_with_extent(concepts::axis auto const axis, concepts::axis auto const extent) noexcept { return axis [extent.value]; } + constexpr auto axis_with_extent(concepts::axis auto const axis, concepts::axis auto const extent) noexcept { return axis[extent.value]; } } diff --git a/include/kwk/settings/type.hpp b/include/kwk/settings/type.hpp index 60f87a9c..8770f417 100644 --- a/include/kwk/settings/type.hpp +++ b/include/kwk/settings/type.hpp @@ -27,7 +27,7 @@ namespace kwk::__ return os << rbr::detail::type.name(); } - friend constexpr bool operator==(info, info) noexcept { return true; } + friend constexpr bool operator==(info, info) noexcept { return true; } constexpr bool operator==(auto) noexcept { return false; } }; @@ -42,6 +42,8 @@ namespace kwk::__ return os << "Type: " << s; } }; + + template consteval auto extent(type_::info) { return std::uint8_t{0}; } // see the note for joker? } namespace kwk diff --git a/include/kwk/utility/container/shape.hpp b/include/kwk/utility/container/shape.hpp index 4963552d..b5573b0d 100644 --- a/include/kwk/utility/container/shape.hpp +++ b/include/kwk/utility/container/shape.hpp @@ -22,6 +22,7 @@ #include #include #include +#include // merely for shape::static_values #include namespace kwk::__ { struct size_; } @@ -178,7 +179,7 @@ namespace kwk //================================================================================================================== template requires(std::is_constructible_v) - KWK_TRIVIAL explicit(sizeof...(T) == 1) constexpr shape(T... d) noexcept : parent(joker::value_type<>{0}, d...) {} + KWK_TRIVIAL explicit(sizeof...(T) == 1) constexpr shape(T... d) noexcept : parent(joker::default_type{0}, d...) {} //================================================================================================================== /// Copy constructor diff --git a/include/kwk/utility/fixed.hpp b/include/kwk/utility/fixed.hpp index 6c2caaa8..be6af59e 100644 --- a/include/kwk/utility/fixed.hpp +++ b/include/kwk/utility/fixed.hpp @@ -7,6 +7,7 @@ //================================================================================================== #pragma once +#include #include #include #include @@ -27,8 +28,8 @@ namespace kwk namespace __ { - template struct to_int { using type = T; }; - template<> struct to_int { using type = joker::value_type<>; }; + template struct to_int{ using type = T; }; + template<> struct to_int; template struct to_int { using type = typename T::stored_value_type; }; template struct to_int { using type = typename T::value_type ; }; @@ -88,14 +89,8 @@ namespace kwk //! @ingroup utility //! @brief Provides a short-cut to define a `std::integral_constant` value from a literal integer //================================================================================================ - template - inline constexpr auto fixed = []() - { - if constexpr(concepts::static_constant) // prevent recursive constant> - return N; - else - return constant{}; - }(); + template< auto N> constexpr auto fixed {constant{}}; + template constexpr auto fixed{ N }; // prevent recursive constant> inline namespace literals { diff --git a/include/kwk/utility/joker.hpp b/include/kwk/utility/joker.hpp index 7c94c701..2eb2dfb0 100644 --- a/include/kwk/utility/joker.hpp +++ b/include/kwk/utility/joker.hpp @@ -11,24 +11,12 @@ #include #include -#ifndef KWK_DEFAULT_AXIS_BITNESS -#define KWK_DEFAULT_AXIS_BITNESS -32 +#ifndef KWK_DEFAULT_JOKER_UNDERLYING_TYPE +#define KWK_DEFAULT_JOKER_UNDERLYING_TYPE int; #endif namespace kwk { - namespace detail - { - template struct int_type; - template <> struct int_type< 8> { using type = std:: int8_t; }; - template <> struct int_type<16> { using type = std::int16_t; }; - template <> struct int_type<32> { using type = std::int32_t; }; - template <> struct int_type<64> { using type = std::int64_t; }; - - template struct as_signed { using type = std::make_unsigned_t; }; - template < typename T> struct as_signed { using type = std:: make_signed_t; }; - } - //================================================================================================ //! @ingroup utility //! @brief Type of the @ref kwk::_ object @@ -45,17 +33,7 @@ namespace kwk KWK_TRIVIAL friend constexpr joker operator*(joker, auto) noexcept { return {}; } KWK_TRIVIAL friend constexpr joker operator*(auto , joker) noexcept { return {}; } - std::int8_t integral_value_type_size = KWK_DEFAULT_AXIS_BITNESS; - - template - constexpr joker operator[](Integral /*const v*/) const noexcept { /*ct_assert(v == 0)*/ return { std::int8_t(sizeof(Integral)) * (std::is_signed_v ? -8 : 8 )}; } - - template - using value_type = typename detail::as_signed - < - bitness < 0, - typename detail::int_type::type - >::type; + using default_type = KWK_DEFAULT_JOKER_UNDERLYING_TYPE; }; //================================================================================================ @@ -88,4 +66,12 @@ namespace kwk //! most meaningful value'. //================================================================================================ inline constexpr joker _ = {}; + + inline constexpr auto extent(joker) noexcept { return joker::default_type{0}; } // use zero as a numeric (compile time) value to represent dynamic/runtime axes? + + namespace __ + { + template struct to_int; + template<> struct to_int { using type = joker::default_type; }; + } } diff --git a/include/kwk/utility/traits/extent.hpp b/include/kwk/utility/traits/extent.hpp index 927b6e4c..eeb17159 100644 --- a/include/kwk/utility/traits/extent.hpp +++ b/include/kwk/utility/traits/extent.hpp @@ -8,8 +8,11 @@ #pragma once #include +#include #include +#include + namespace kwk { template @@ -55,4 +58,9 @@ namespace kwk template struct is_static_extent : std::bool_constant> {}; + + // thin as_dimension + constexpr auto extent(std::integral auto const dim) noexcept { return dim; } + constexpr auto extent(concepts::axis auto const dim) noexcept { return dim.value; } + constexpr auto extent(concepts::static_constant auto const dim) noexcept { return dim; } } From 6b3271d8aeb31cc6c38b103698af387833944932 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domagoj=20=C5=A0ari=C4=87?= Date: Thu, 3 Aug 2023 17:02:57 +0200 Subject: [PATCH 22/30] Simplified KWK_DEFAULT_SHAPE* logic. --- include/kwk/detail/sequence/shape_constraints.hpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/include/kwk/detail/sequence/shape_constraints.hpp b/include/kwk/detail/sequence/shape_constraints.hpp index c93dcf8f..fd180891 100644 --- a/include/kwk/detail/sequence/shape_constraints.hpp +++ b/include/kwk/detail/sequence/shape_constraints.hpp @@ -7,14 +7,14 @@ //====================================================================================================================== #pragma once +#if defined(KWK_DEFAULT_SHAPE_CONSTRAINTS_INCLUDE) +#include KWK_DEFAULT_SHAPE_CONSTRAINTS_INCLUDE +#else + #include #include -#if !defined(KWK_DEFAULT_SHAPE_CONSTRAINTS) #define KWK_DEFAULT_SHAPE_CONSTRAINTS ::kwk::basic_shape_checks -#elif defined(KWK_DEFAULT_SHAPE_CONSTRAINTS_INCLUDE) -#include KWK_DEFAULT_SHAPE_CONSTRAINTS_INCLUDE -#endif namespace kwk { @@ -86,3 +86,5 @@ namespace kwk } }; } + +#endif // KWK_DEFAULT_SHAPE_CONSTRAINTS_INCLUDE From 01fa3e596d0a9829e550e7b4762780a5ac5d231c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domagoj=20=C5=A0ari=C4=87?= Date: Thu, 3 Aug 2023 17:03:21 +0200 Subject: [PATCH 23/30] Updated the unit tests with the latest changes. --- test/docs/shape/numerical_axis.cpp | 2 +- test/utility/shape/default_ctor.cpp | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/test/docs/shape/numerical_axis.cpp b/test/docs/shape/numerical_axis.cpp index c25ad394..1a18d886 100644 --- a/test/docs/shape/numerical_axis.cpp +++ b/test/docs/shape/numerical_axis.cpp @@ -33,7 +33,7 @@ int main() //==================================================================================================================== // Numerical extents with type specifier //==================================================================================================================== - kwk::shape> s7(100,100); + kwk::shape> s7(std::uint8_t{100},std::uint8_t{100}); std::cout << "Size of s7: " << sizeof(s7) << "\n"; std::cout << s7 << "\n"; diff --git a/test/utility/shape/default_ctor.cpp b/test/utility/shape/default_ctor.cpp index 9f88e60f..5c417141 100644 --- a/test/utility/shape/default_ctor.cpp +++ b/test/utility/shape/default_ctor.cpp @@ -7,11 +7,12 @@ //================================================================================================== #include "test.hpp" #include +#include #include "utility/shape/shape.hpp" using kwk::_; -using axis_base_type = decltype(kwk::along<0>)::base_type; +using axis_base_type = kwk::joker::default_type; TTS_CASE( "Default constructed shape behavior - Mixed 1D") { From dd4c6e1159323d6ad5274126deb91ab36a570efd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domagoj=20=C5=A0ari=C4=87?= Date: Thu, 3 Aug 2023 20:24:18 +0200 Subject: [PATCH 24/30] Made constant usable in assume statements w/o compiler warnings. --- include/kwk/utility/fixed.hpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/include/kwk/utility/fixed.hpp b/include/kwk/utility/fixed.hpp index be6af59e..7538e6d6 100644 --- a/include/kwk/utility/fixed.hpp +++ b/include/kwk/utility/fixed.hpp @@ -64,13 +64,15 @@ namespace kwk template struct constant : std::integral_constant { + KWK_CONST KWK_TRIVIAL constexpr operator decltype(N)() const noexcept { return N; } + friend std::ostream& operator<<(std::ostream& os, constant) { return os << +N << "_c"; } - KWK_TRIVIAL constexpr auto operator-() const noexcept { return constant<-N>{}; } - KWK_TRIVIAL constexpr auto operator+() const noexcept { return *this; } + KWK_CONST KWK_TRIVIAL constexpr auto operator-() const noexcept { return constant<-N>{}; } + KWK_CONST KWK_TRIVIAL constexpr auto operator+() const noexcept { return *this; } }; template From 3649d355c7d8388ca7f033a7bff0ace703acb8b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domagoj=20=C5=A0ari=C4=87?= Date: Thu, 3 Aug 2023 20:31:23 +0200 Subject: [PATCH 25/30] Ditto extent. --- include/kwk/utility/traits/extent.hpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/include/kwk/utility/traits/extent.hpp b/include/kwk/utility/traits/extent.hpp index eeb17159..deee956f 100644 --- a/include/kwk/utility/traits/extent.hpp +++ b/include/kwk/utility/traits/extent.hpp @@ -9,6 +9,7 @@ #include #include +#include #include #include @@ -60,7 +61,7 @@ namespace kwk {}; // thin as_dimension - constexpr auto extent(std::integral auto const dim) noexcept { return dim; } - constexpr auto extent(concepts::axis auto const dim) noexcept { return dim.value; } - constexpr auto extent(concepts::static_constant auto const dim) noexcept { return dim; } + KWK_CONST constexpr auto extent(std::integral auto const dim) noexcept { return dim; } + KWK_CONST constexpr auto extent(concepts::axis auto const dim) noexcept { return dim.value; } + KWK_CONST constexpr auto extent(concepts::static_constant auto const dim) noexcept { return dim; } } From 0c34146293e237131fb04e2ad09bcaed02ab8b0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domagoj=20=C5=A0ari=C4=87?= Date: Thu, 3 Aug 2023 20:40:25 +0200 Subject: [PATCH 26/30] Missing axis_with_extent for type_info. --- include/kwk/settings/type.hpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/include/kwk/settings/type.hpp b/include/kwk/settings/type.hpp index 8770f417..a03c6cee 100644 --- a/include/kwk/settings/type.hpp +++ b/include/kwk/settings/type.hpp @@ -10,6 +10,8 @@ #include #include +namespace kwk { struct joker; } + namespace kwk::__ { struct type_ : rbr::as_keyword @@ -44,10 +46,15 @@ namespace kwk::__ }; template consteval auto extent(type_::info) { return std::uint8_t{0}; } // see the note for joker? + template consteval T axis_with_extent(type_::info, auto const extent) noexcept { return {extent}; } + template consteval auto axis_with_extent(type_::info, joker ) noexcept { return type_::info{}; } } namespace kwk { + using __::extent; + using __::axis_with_extent; + constexpr inline __::type_ value_type{}; template From 6afa7f755ba2bb13b9a1ef1df81a3a2b8c398d7f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domagoj=20=C5=A0ari=C4=87?= Date: Thu, 3 Aug 2023 20:56:51 +0200 Subject: [PATCH 27/30] Fixed (hopefully) axis == integral and joker comparisons. --- include/kwk/settings/axis.hpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/include/kwk/settings/axis.hpp b/include/kwk/settings/axis.hpp index 2eb2bb99..4a4b1774 100644 --- a/include/kwk/settings/axis.hpp +++ b/include/kwk/settings/axis.hpp @@ -15,6 +15,7 @@ #include #include #include +#include #include #include @@ -22,6 +23,8 @@ namespace kwk { struct joker; } namespace kwk::__ { + struct type_; + template constexpr bool is_implicit { false }; template constexpr bool is_implicit{ ID < 0 }; @@ -103,9 +106,13 @@ namespace kwk::__ return axis_{v}; } - template - KWK_PURE constexpr bool operator ==(T const v) const noexcept requires(!concepts::axis) { return value == v; } - KWK_PURE constexpr bool operator ==(joker ) const noexcept { return std::same_as; } + template requires( !concepts::axis ) + KWK_PURE constexpr bool operator ==(T const v) const noexcept + requires requires{ { (Content const){} == v } -> std::convertible_to; } // poorman's std::equality_comparable_with + { return value == v; } + + // test whether an axis has an unspecified (runtime) value + KWK_PURE constexpr bool operator==( joker ) const noexcept { return std::same_as || requires{ requires std::same_as; }; } KWK_PURE explicit constexpr operator Content () const noexcept { return value; } KWK_PURE constexpr Content operator*() const noexcept { return value; } From f4cd4ed1fc57bc0fa2204a27b9b1fce70d82a996 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domagoj=20=C5=A0ari=C4=87?= Date: Wed, 9 Aug 2023 16:47:20 +0200 Subject: [PATCH 28/30] Properly fixed the issue of shape<> not being trivially copyable. --- include/kwk/utility/container/shape.hpp | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/include/kwk/utility/container/shape.hpp b/include/kwk/utility/container/shape.hpp index b5573b0d..7f9364f2 100644 --- a/include/kwk/utility/container/shape.hpp +++ b/include/kwk/utility/container/shape.hpp @@ -75,11 +75,7 @@ namespace kwk //! @tparam D List of @ref glossary-extent types //==================================================================================================================== template - struct -#ifdef __clang__ - [[clang::trivial_abi]] -#endif - shape : __::prefilled_t::type + struct shape : __::prefilled_t::type { using parent = typename __::prefilled_t::type; using constraint_t = KWK_DEFAULT_SHAPE_CONSTRAINTS; @@ -184,8 +180,7 @@ namespace kwk //================================================================================================================== /// Copy constructor //================================================================================================================== - KWK_TRIVIAL constexpr shape(shape const& d) noexcept : parent(d) - {} + constexpr shape(shape const&) noexcept = default; //================================================================================================================== //! @brief Construct shape from another shape type @@ -209,15 +204,11 @@ namespace kwk //================================================================================================================== /// Assignment operator //================================================================================================================== - constexpr shape& operator=( shape const& other ) & noexcept - { - this->__base() = other.__base(); - return *this; - } + constexpr shape& operator=( shape const& other ) noexcept = default; template requires( constraint_t::is_contructible_from::parent{}>() ) - constexpr shape& operator=( shape const& other ) & noexcept + constexpr shape& operator=( shape const& other ) noexcept { constraint_t::construct(*this, other); return *this; From 07af4bde9e9625d3792e1e4d52535cc6e7a87af6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nenad=20Miks=CC=8Ca?= Date: Tue, 2 Jan 2024 19:01:58 +0100 Subject: [PATCH 29/30] use std::equality_comparable_with which is now fully supported --- include/kwk/settings/axis.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/kwk/settings/axis.hpp b/include/kwk/settings/axis.hpp index 4a4b1774..404dd5bb 100644 --- a/include/kwk/settings/axis.hpp +++ b/include/kwk/settings/axis.hpp @@ -108,7 +108,7 @@ namespace kwk::__ template requires( !concepts::axis ) KWK_PURE constexpr bool operator ==(T const v) const noexcept - requires requires{ { (Content const){} == v } -> std::convertible_to; } // poorman's std::equality_comparable_with + requires std::equality_comparable_with { return value == v; } // test whether an axis has an unspecified (runtime) value From 72e45dabad1b8cb1e91b661fd071c828e76df8bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nenad=20Miks=CC=8Ca?= Date: Tue, 2 Jan 2024 19:10:17 +0100 Subject: [PATCH 30/30] fix narrowing cast --- include/kwk/detail/sequence/prefilled.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/kwk/detail/sequence/prefilled.hpp b/include/kwk/detail/sequence/prefilled.hpp index d8e60a90..cad32db8 100644 --- a/include/kwk/detail/sequence/prefilled.hpp +++ b/include/kwk/detail/sequence/prefilled.hpp @@ -101,7 +101,7 @@ namespace kwk::__ if constexpr(is_fully_dynamic) { using kwk::extent; - static_cast(*this) = storage_type{extent(vs)...}; + static_cast(*this) = storage_type{stored_t(extent(vs))...}; } else {