From bab0e249f25a94f282a481e5cae828e1846b75c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20S=C3=BC=C3=9Fenbach?= Date: Tue, 17 Oct 2023 08:52:54 +0200 Subject: [PATCH] Improve implicit conversion operators of vk::ArrayWrapper1D on char type; added constructors from std::string and std::string_view (#1698) --- snippets/ArrayWrapper1D.hpp | 240 +++++++++++++++------------- tests/ArrayWrapper/ArrayWrapper.cpp | 64 ++++++++ tests/ArrayWrapper/CMakeLists.txt | 17 ++ tests/CMakeLists.txt | 1 + vulkan/vulkan.hpp | 34 +++- vulkan/vulkansc.hpp | 34 +++- 6 files changed, 276 insertions(+), 114 deletions(-) create mode 100644 tests/ArrayWrapper/ArrayWrapper.cpp create mode 100644 tests/ArrayWrapper/CMakeLists.txt diff --git a/snippets/ArrayWrapper1D.hpp b/snippets/ArrayWrapper1D.hpp index 5e9cfa1..542ead3 100644 --- a/snippets/ArrayWrapper1D.hpp +++ b/snippets/ArrayWrapper1D.hpp @@ -1,130 +1,154 @@ - template - class ArrayWrapper1D : public std::array +template +class ArrayWrapper1D : public std::array +{ +public: + VULKAN_HPP_CONSTEXPR ArrayWrapper1D() VULKAN_HPP_NOEXCEPT : std::array() {} + + VULKAN_HPP_CONSTEXPR ArrayWrapper1D( std::array const & data ) VULKAN_HPP_NOEXCEPT : std::array( data ) {} + + template ::value, int>::type = 0> + VULKAN_HPP_CONSTEXPR_14 ArrayWrapper1D( std::string const & data ) VULKAN_HPP_NOEXCEPT { - public: - VULKAN_HPP_CONSTEXPR ArrayWrapper1D() VULKAN_HPP_NOEXCEPT - : std::array() - {} - - VULKAN_HPP_CONSTEXPR ArrayWrapper1D( std::array const & data ) VULKAN_HPP_NOEXCEPT - : std::array( data ) - {} - -#if ( VK_USE_64_BIT_PTR_DEFINES == 0 ) - // on 32 bit compiles, needs overloads on index type int to resolve ambiguities - VULKAN_HPP_CONSTEXPR T const & operator[]( int index ) const VULKAN_HPP_NOEXCEPT - { - return std::array::operator[]( index ); - } - - T & operator[]( int index ) VULKAN_HPP_NOEXCEPT - { - return std::array::operator[]( index ); - } -#endif - - operator T const * () const VULKAN_HPP_NOEXCEPT - { - return this->data(); - } - - operator T * () VULKAN_HPP_NOEXCEPT - { - return this->data(); - } - - template ::value, int>::type = 0> - operator std::string() const - { - return std::string( this->data() ); - } + copy( data.data(), data.length() ); + } #if 17 <= VULKAN_HPP_CPP_VERSION - template ::value, int>::type = 0> - operator std::string_view() const - { - return std::string_view( this->data() ); - } + template ::value, int>::type = 0> + VULKAN_HPP_CONSTEXPR_14 ArrayWrapper1D( std::string_view data ) VULKAN_HPP_NOEXCEPT + { + copy( data.data(), data.length() ); + } +#endif + +#if ( VK_USE_64_BIT_PTR_DEFINES == 0 ) + // on 32 bit compiles, needs overloads on index type int to resolve ambiguities + VULKAN_HPP_CONSTEXPR T const & operator[]( int index ) const VULKAN_HPP_NOEXCEPT + { + return std::array::operator[]( index ); + } + + T & operator[]( int index ) VULKAN_HPP_NOEXCEPT + { + return std::array::operator[]( index ); + } +#endif + + operator T const *() const VULKAN_HPP_NOEXCEPT + { + return this->data(); + } + + operator T *() VULKAN_HPP_NOEXCEPT + { + return this->data(); + } + + template ::value, int>::type = 0> + operator std::string() const + { + return std::string( this->data(), N ); + } + +#if 17 <= VULKAN_HPP_CPP_VERSION + template ::value, int>::type = 0> + operator std::string_view() const + { + return std::string_view( this->data(), N ); + } #endif #if defined( VULKAN_HPP_HAS_SPACESHIP_OPERATOR ) - template ::value, int>::type = 0> - std::strong_ordering operator<=>( ArrayWrapper1D const & rhs ) const VULKAN_HPP_NOEXCEPT - { - return *static_cast const *>( this ) <=> *static_cast const *>( &rhs ); - } + template ::value, int>::type = 0> + std::strong_ordering operator<=>( ArrayWrapper1D const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return *static_cast const *>( this ) <=> *static_cast const *>( &rhs ); + } #else - template ::value, int>::type = 0> - bool operator<( ArrayWrapper1D const & rhs ) const VULKAN_HPP_NOEXCEPT - { - return *static_cast const *>( this ) < *static_cast const *>( &rhs ); - } + template ::value, int>::type = 0> + bool operator<( ArrayWrapper1D const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return *static_cast const *>( this ) < *static_cast const *>( &rhs ); + } - template ::value, int>::type = 0> - bool operator<=( ArrayWrapper1D const & rhs ) const VULKAN_HPP_NOEXCEPT - { - return *static_cast const *>( this ) <= *static_cast const *>( &rhs ); - } + template ::value, int>::type = 0> + bool operator<=( ArrayWrapper1D const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return *static_cast const *>( this ) <= *static_cast const *>( &rhs ); + } - template ::value, int>::type = 0> - bool operator>( ArrayWrapper1D const & rhs ) const VULKAN_HPP_NOEXCEPT - { - return *static_cast const *>( this ) > *static_cast const *>( &rhs ); - } + template ::value, int>::type = 0> + bool operator>( ArrayWrapper1D const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return *static_cast const *>( this ) > *static_cast const *>( &rhs ); + } - template ::value, int>::type = 0> - bool operator>=( ArrayWrapper1D const & rhs ) const VULKAN_HPP_NOEXCEPT - { - return *static_cast const *>( this ) >= *static_cast const *>( &rhs ); - } + template ::value, int>::type = 0> + bool operator>=( ArrayWrapper1D const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return *static_cast const *>( this ) >= *static_cast const *>( &rhs ); + } #endif - template ::value, int>::type = 0> - bool operator==( ArrayWrapper1D const & rhs ) const VULKAN_HPP_NOEXCEPT + template ::value, int>::type = 0> + bool operator==( ArrayWrapper1D const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return *static_cast const *>( this ) == *static_cast const *>( &rhs ); + } + + template ::value, int>::type = 0> + bool operator!=( ArrayWrapper1D const & rhs ) const VULKAN_HPP_NOEXCEPT + { + return *static_cast const *>( this ) != *static_cast const *>( &rhs ); + } + +private: + VULKAN_HPP_CONSTEXPR_14 void copy( char const * data, size_t len ) const VULKAN_HPP_NOEXCEPT + { + size_t n = std::min( N, len ); + for ( size_t i = 0; i < n; ++i ) { - return *static_cast const *>( this ) == *static_cast const *>( &rhs ); + ( *this )[i] = data[i]; } - - template ::value, int>::type = 0> - bool operator!=( ArrayWrapper1D const & rhs ) const VULKAN_HPP_NOEXCEPT + for ( size_t i = n; i < N; ++i ) { - return *static_cast const *>( this ) != *static_cast const *>( &rhs ); + ( *this )[i] = 0; } - }; - - // specialization of relational operators between std::string and arrays of chars - template - bool operator<( std::string const & lhs, ArrayWrapper1D const & rhs ) VULKAN_HPP_NOEXCEPT - { - return lhs < rhs.data(); } +}; - template - bool operator<=( std::string const & lhs, ArrayWrapper1D const & rhs ) VULKAN_HPP_NOEXCEPT - { - return lhs <= rhs.data(); - } +// specialization of relational operators between std::string and arrays of chars +template +bool operator<( std::string const & lhs, ArrayWrapper1D const & rhs ) VULKAN_HPP_NOEXCEPT +{ + return lhs < rhs.data(); +} - template - bool operator>( std::string const & lhs, ArrayWrapper1D const & rhs ) VULKAN_HPP_NOEXCEPT - { - return lhs > rhs.data(); - } +template +bool operator<=( std::string const & lhs, ArrayWrapper1D const & rhs ) VULKAN_HPP_NOEXCEPT +{ + return lhs <= rhs.data(); +} - template - bool operator>=( std::string const & lhs, ArrayWrapper1D const & rhs ) VULKAN_HPP_NOEXCEPT - { - return lhs >= rhs.data(); - } +template +bool operator>( std::string const & lhs, ArrayWrapper1D const & rhs ) VULKAN_HPP_NOEXCEPT +{ + return lhs > rhs.data(); +} - template - bool operator==( std::string const & lhs, ArrayWrapper1D const & rhs ) VULKAN_HPP_NOEXCEPT - { - return lhs == rhs.data(); - } +template +bool operator>=( std::string const & lhs, ArrayWrapper1D const & rhs ) VULKAN_HPP_NOEXCEPT +{ + return lhs >= rhs.data(); +} - template - bool operator!=( std::string const & lhs, ArrayWrapper1D const & rhs ) VULKAN_HPP_NOEXCEPT - { - return lhs != rhs.data(); - } +template +bool operator==( std::string const & lhs, ArrayWrapper1D const & rhs ) VULKAN_HPP_NOEXCEPT +{ + return lhs == rhs.data(); +} + +template +bool operator!=( std::string const & lhs, ArrayWrapper1D const & rhs ) VULKAN_HPP_NOEXCEPT +{ + return lhs != rhs.data(); +} diff --git a/tests/ArrayWrapper/ArrayWrapper.cpp b/tests/ArrayWrapper/ArrayWrapper.cpp new file mode 100644 index 0000000..2243d6b --- /dev/null +++ b/tests/ArrayWrapper/ArrayWrapper.cpp @@ -0,0 +1,64 @@ +// Copyright(c) 2023, NVIDIA CORPORATION. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +// +// VulkanHpp Samples : ArrayWrapper +// Compile test on using vk::ArrayWrapper1D + +#include +#include +#include + +void f( std::string const & s ) +{ + std::cout << "<" << s << ">" << std::endl; +} + +using namespace std::string_literals; + +int main( int /*argc*/, char ** /*argv*/ ) +{ + vk::ArrayWrapper1D aw1( { 'f', 'o', 'o', 'b', 'a', 'h' } ); + std::string s1 = aw1; + assert( s1.length() == 10 ); + std::cout << "<" << aw1 << ">" << std::endl; + + // s1 = aw1; // 'operator =' is ambiguous + + vk::ArrayWrapper1D aw2( "foobah"s ); + f( aw2 ); + + vk::ArrayWrapper1D aw3( { 'f', 'o', 'o', 'b', 'a', 'h' } ); + std::string s3 = aw3; + assert( s3.length() == 5 ); + std::cout << "<" << s3 << ">" << std::endl; + + vk::ArrayWrapper1D aw4( "foobah"s ); + std::string s4 = aw4; + assert( s4.length() == 5 ); + +#if 17 <= VULKAN_HPP_CPP_VERSION + std::cout << std::boolalpha << std::is_convertible_v, std::string_view> << std::endl; + + std::string_view sv1 = aw1; + assert( sv1.size() == 10 ); + sv1 = aw2; + assert( sv1.size() == 20 ); + sv1 = aw3; + assert( sv1.size() == 5 ); + + vk::ArrayWrapper1D aw5( sv1 ); +#endif + + return 0; +} diff --git a/tests/ArrayWrapper/CMakeLists.txt b/tests/ArrayWrapper/CMakeLists.txt new file mode 100644 index 0000000..843b6ba --- /dev/null +++ b/tests/ArrayWrapper/CMakeLists.txt @@ -0,0 +1,17 @@ +# Copyright(c) 2023, NVIDIA CORPORATION. All rights reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +if( NOT VULKAN_HPP_TESTS_BUILD_ONLY_DYNAMIC ) + vulkan_hpp__setup_test( NAME ArrayWrapper ) +endif() \ No newline at end of file diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 1f51d4a..b04a4c9 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -14,6 +14,7 @@ add_subdirectory( ArrayProxy ) add_subdirectory( ArrayProxyNoTemporaries ) +add_subdirectory( ArrayWrapper ) add_subdirectory( DesignatedInitializers ) add_subdirectory( DeviceFunctions ) add_subdirectory( DispatchLoaderDynamic ) diff --git a/vulkan/vulkan.hpp b/vulkan/vulkan.hpp index 6fb1cf0..a094d67 100644 --- a/vulkan/vulkan.hpp +++ b/vulkan/vulkan.hpp @@ -94,6 +94,20 @@ namespace VULKAN_HPP_NAMESPACE VULKAN_HPP_CONSTEXPR ArrayWrapper1D( std::array const & data ) VULKAN_HPP_NOEXCEPT : std::array( data ) {} + template ::value, int>::type = 0> + VULKAN_HPP_CONSTEXPR_14 ArrayWrapper1D( std::string const & data ) VULKAN_HPP_NOEXCEPT + { + copy( data.data(), data.length() ); + } + +#if 17 <= VULKAN_HPP_CPP_VERSION + template ::value, int>::type = 0> + VULKAN_HPP_CONSTEXPR_14 ArrayWrapper1D( std::string_view data ) VULKAN_HPP_NOEXCEPT + { + copy( data.data(), data.length() ); + } +#endif + #if ( VK_USE_64_BIT_PTR_DEFINES == 0 ) // on 32 bit compiles, needs overloads on index type int to resolve ambiguities VULKAN_HPP_CONSTEXPR T const & operator[]( int index ) const VULKAN_HPP_NOEXCEPT @@ -120,14 +134,14 @@ namespace VULKAN_HPP_NAMESPACE template ::value, int>::type = 0> operator std::string() const { - return std::string( this->data() ); + return std::string( this->data(), N ); } #if 17 <= VULKAN_HPP_CPP_VERSION template ::value, int>::type = 0> operator std::string_view() const { - return std::string_view( this->data() ); + return std::string_view( this->data(), N ); } #endif @@ -174,6 +188,20 @@ namespace VULKAN_HPP_NAMESPACE { return *static_cast const *>( this ) != *static_cast const *>( &rhs ); } + + private: + VULKAN_HPP_CONSTEXPR_14 void copy( char const * data, size_t len ) const VULKAN_HPP_NOEXCEPT + { + size_t n = std::min( N, len ); + for ( size_t i = 0; i < n; ++i ) + { + ( *this )[i] = data[i]; + } + for ( size_t i = n; i < N; ++i ) + { + ( *this )[i] = 0; + } + } }; // specialization of relational operators between std::string and arrays of chars @@ -14168,7 +14196,7 @@ namespace VULKAN_HPP_NAMESPACE # elif defined( __APPLE__ ) m_library = dlopen( "libvulkan.dylib", RTLD_NOW | RTLD_LOCAL ); # elif defined( _WIN32 ) - m_library = ::LoadLibraryA( "vulkan-1.dll" ); + m_library = ::LoadLibraryA( "vulkan-1.dll" ); # else # error unsupported platform # endif diff --git a/vulkan/vulkansc.hpp b/vulkan/vulkansc.hpp index fb180d0..d6c7707 100644 --- a/vulkan/vulkansc.hpp +++ b/vulkan/vulkansc.hpp @@ -94,6 +94,20 @@ namespace VULKAN_HPP_NAMESPACE VULKAN_HPP_CONSTEXPR ArrayWrapper1D( std::array const & data ) VULKAN_HPP_NOEXCEPT : std::array( data ) {} + template ::value, int>::type = 0> + VULKAN_HPP_CONSTEXPR_14 ArrayWrapper1D( std::string const & data ) VULKAN_HPP_NOEXCEPT + { + copy( data.data(), data.length() ); + } + +#if 17 <= VULKAN_HPP_CPP_VERSION + template ::value, int>::type = 0> + VULKAN_HPP_CONSTEXPR_14 ArrayWrapper1D( std::string_view data ) VULKAN_HPP_NOEXCEPT + { + copy( data.data(), data.length() ); + } +#endif + #if ( VK_USE_64_BIT_PTR_DEFINES == 0 ) // on 32 bit compiles, needs overloads on index type int to resolve ambiguities VULKAN_HPP_CONSTEXPR T const & operator[]( int index ) const VULKAN_HPP_NOEXCEPT @@ -120,14 +134,14 @@ namespace VULKAN_HPP_NAMESPACE template ::value, int>::type = 0> operator std::string() const { - return std::string( this->data() ); + return std::string( this->data(), N ); } #if 17 <= VULKAN_HPP_CPP_VERSION template ::value, int>::type = 0> operator std::string_view() const { - return std::string_view( this->data() ); + return std::string_view( this->data(), N ); } #endif @@ -174,6 +188,20 @@ namespace VULKAN_HPP_NAMESPACE { return *static_cast const *>( this ) != *static_cast const *>( &rhs ); } + + private: + VULKAN_HPP_CONSTEXPR_14 void copy( char const * data, size_t len ) const VULKAN_HPP_NOEXCEPT + { + size_t n = std::min( N, len ); + for ( size_t i = 0; i < n; ++i ) + { + ( *this )[i] = data[i]; + } + for ( size_t i = n; i < N; ++i ) + { + ( *this )[i] = 0; + } + } }; // specialization of relational operators between std::string and arrays of chars @@ -6601,7 +6629,7 @@ namespace VULKAN_HPP_NAMESPACE # elif defined( __APPLE__ ) m_library = dlopen( "libvulkan.dylib", RTLD_NOW | RTLD_LOCAL ); # elif defined( _WIN32 ) - m_library = ::LoadLibraryA( "vulkan-1.dll" ); + m_library = ::LoadLibraryA( "vulkan-1.dll" ); # else # error unsupported platform # endif