From 4d62df488b8e421cadfbd8648b813d7494a56153 Mon Sep 17 00:00:00 2001 From: Lotendan <85304370+Lotendan@users.noreply.github.com> Date: Thu, 2 Mar 2023 21:34:49 +0100 Subject: [PATCH] Add support for initializer_list to wx dynamic arrays While these array classes are deprecated in the user code, they're still used, for compatibility, in many places in wxWidgets API and allowing to create them from initializer_list makes using it more ergonomic as it's now possible to just pass an initializer list of items to fill the control with, for example, instead of appending them one by one. Closes #23309. --- include/wx/arrstr.h | 6 ++++++ include/wx/dynarray.h | 7 +++++++ interface/wx/arrstr.h | 8 ++++++++ interface/wx/dynarray.h | 8 ++++++++ tests/arrays/arrays.cpp | 16 ++++++++++++++++ 5 files changed, 45 insertions(+) diff --git a/include/wx/arrstr.h b/include/wx/arrstr.h index 7645c00822..3d10040349 100644 --- a/include/wx/arrstr.h +++ b/include/wx/arrstr.h @@ -16,6 +16,7 @@ #include "wx/dynarray.h" #include +#include // these functions are only used in STL build now but we define them in any // case for compatibility with the existing code outside of the library which @@ -81,6 +82,8 @@ public: wxArrayString(size_t sz, const char** a); wxArrayString(size_t sz, const wchar_t** a); wxArrayString(size_t sz, const wxString* a); + template + wxArrayString(std::initializer_list list) : wxArrayStringBase(list) { } int Index(const wxString& str, bool bCase = true, bool bFromEnd = false) const; @@ -182,6 +185,9 @@ public: wxArrayString(size_t sz, const wxString* a); // copy ctor wxArrayString(const wxArrayString& array); + // list constructor + template + wxArrayString(std::initializer_list list) { Init(false); assign(list.begin(), list.end()); } // assignment operator wxArrayString& operator=(const wxArrayString& src); // not virtual, this class should not be derived from diff --git a/include/wx/dynarray.h b/include/wx/dynarray.h index c5cddbd0b4..02cc4b2faf 100644 --- a/include/wx/dynarray.h +++ b/include/wx/dynarray.h @@ -15,6 +15,8 @@ #include "wx/vector.h" +#include + /* This header defines legacy dynamic arrays and object arrays (i.e. arrays which own their elements) classes. @@ -105,6 +107,9 @@ public: : base_vec(first, last) { } + template + wxBaseArray(std::initializer_list list) : base_vec(list.begin(), list.end()) {} + void Empty() { this->clear(); } void Clear() { this->clear(); } void Alloc(size_t uiSize) { this->reserve(uiSize); } @@ -515,6 +520,8 @@ private: name(size_t n, Base::const_reference v) : Base(n, v) { } \ template \ name(InputIterator first, InputIterator last) : Base(first, last) { } \ + template \ + name(std::initializer_list list) : Base(list.begin(), list.end()) { } \ } diff --git a/interface/wx/arrstr.h b/interface/wx/arrstr.h index 5a005dd822..ec7d80c7f9 100644 --- a/interface/wx/arrstr.h +++ b/interface/wx/arrstr.h @@ -89,6 +89,14 @@ public: */ wxArrayString(size_t sz, const wxString* arr); + /** + Constructs the container with the contents of the initializer_list @a list. + + @since 3.2.3 + */ + template + wxArrayString(std::initializer_list list); + /** Destructor frees memory occupied by the array strings. For performance reasons it is not virtual, so this class should not be derived from. diff --git a/interface/wx/dynarray.h b/interface/wx/dynarray.h index a5a8680f85..384d1b9614 100644 --- a/interface/wx/dynarray.h +++ b/interface/wx/dynarray.h @@ -271,6 +271,14 @@ public: */ wxObjArray(const wxObjArray& array); + /** + Constructs the container with the contents of the initializer_list @a list. + + @since 3.2.3 + */ + template + wxArray(std::initializer_list list); + /** Performs a shallow array copy (i.e.\ doesn't copy the objects pointed to even if the source array contains the items of pointer type). diff --git a/tests/arrays/arrays.cpp b/tests/arrays/arrays.cpp index 7028a5d321..c5547b6747 100644 --- a/tests/arrays/arrays.cpp +++ b/tests/arrays/arrays.cpp @@ -340,6 +340,19 @@ TEST_CASE("wxArrayString", "[dynarray]") CHECK( a7.size() == 1 ); wxCLANG_WARNING_RESTORE(self-assign-overloaded) + + wxArrayString a8( { wxT("dog"), wxT("human"), wxT("condor"), wxT("thermit"), wxT("alligator") } ); + CHECK( a8.size() == 5 ); + CHECK( a8[1] == "human" ); + CHECK( a8[4] == "alligator" ); + + a8 = { wxT("Foo") }; // Test operator= + CHECK( a8.size() == 1 ); + CHECK( a8[0] == "Foo" ); + + // Same test with std::initializer_list + wxArrayString a9( { std::string("dog"), std::string("human"), std::string("condor"), std::string("thermit"), std::string("alligator") } ); + CHECK( a9.size() == 5 ); } TEST_CASE("wxSortedArrayString", "[dynarray]") @@ -623,6 +636,9 @@ TEST_CASE("wxDynArray::" #name, "[dynarray]") \ CHECK( b.Index( 5 ) == 2 ); \ CHECK( b.Index( 6 ) == wxNOT_FOUND ); \ CHECK( b.Index( 17 ) == 3 ); \ + \ + wxArray##name c({1,2,3}); \ + CHECK(c.size() == 3); \ } TestArrayOf(UShort)