Add wxArrayString::AsVector() too

This provides the conversion in the other direction, which is needed
less often but it's still arguably better to have it than not to.
This commit is contained in:
Vadim Zeitlin 2023-04-08 22:45:11 +01:00
parent 23981273df
commit e832ebbacc
4 changed files with 63 additions and 4 deletions

View file

@ -95,6 +95,8 @@ public:
wxBaseArray<wxString>::Add(string, copies);
return size() - copies;
}
const std::vector<wxString>& AsVector() const { return *this; }
};
// Unlike all the other sorted arrays, this one uses a comparison function
@ -240,6 +242,8 @@ public:
}
const wxString& Last() const { return const_cast<wxArrayString*>(this)->Last(); }
// get all items as a vector
std::vector<wxString> AsVector() const;
// item management
// Search the element in the array, starting from the beginning if

View file

@ -32,10 +32,30 @@
countries);
@endcode
When using a wxWidgets function returning an object of this class, you can
either use it as if it were a `std::vector<wxString>`, as this class has
all vector methods, or actually convert it to such vector using its
AsVector(), e.g.
If you do use this class directly, it's recommended to prefer using its
`std::vector<wxString>`-like methods instead of the legacy wxArray-like
ones.
@code
wxArrayString files;
wxDir::GetAllFiles("/some/path", &files);
// Can use the usual accessors:
if ( !files.empty() ) {
auto first = files[0];
auto total = files.size();
...
}
// Can iterate over it like over a vector, too.
for ( const wxString& file: files ) {
...
}
// Or can just convert it to the "real" vector:
const std::vector<wxString>& vec = files.AsVector();
@endcode
@library{wxbase}
@category{containers}
@ -135,6 +155,25 @@ public:
*/
void Alloc(size_t nCount);
/**
Constructs a std::vector containing the same strings as this array.
In @ref overview_container_std, this function actually returns a const
reference to this object itself, without making a copy, but in the
default/compatible build, it has to copy all the strings, making it
expensive to call for big arrays.
Note that using it like this:
@code
const std::vector<wxString>& vec = array.AsVector();
@endcode
works in all builds as long as you don't need to modify the returned
vector and doesn't impose any extra overhead in the STL build.
@since 3.3.0
*/
std::vector<wxString> AsVector() const;
/**
Clears the array contents and frees memory.

View file

@ -150,6 +150,14 @@ wxArrayString& wxArrayString::operator=(const wxArrayString& src)
return *this;
}
std::vector<wxString> wxArrayString::AsVector() const
{
if ( !m_pItems )
return {};
return std::vector<wxString>{m_pItems, m_pItems + m_nCount};
}
void wxArrayString::Copy(const wxArrayString& src)
{
if ( src.m_nCount > ARRAY_DEFAULT_INITIAL_SIZE )

View file

@ -355,7 +355,7 @@ TEST_CASE("wxArrayString", "[dynarray]")
CHECK( a9.size() == 5 );
}
TEST_CASE("wxArrayString::FromVector", "[dynarray][vector]")
TEST_CASE("wxArrayString::Vector", "[dynarray][vector]")
{
SECTION("wxString")
{
@ -372,6 +372,14 @@ TEST_CASE("wxArrayString::FromVector", "[dynarray][vector]")
REQUIRE( a.size() == 2 );
CHECK( a[1] == "fourth" );
}
SECTION("AsVector")
{
wxArrayString a{"five", "six", "seven"};
const std::vector<wxString>& vec = a.AsVector();
REQUIRE( vec.size() == 3 );
CHECK( vec.at(2) == "seven" );
}
}
TEST_CASE("wxSortedArrayString", "[dynarray]")