From 0d5378fb840529e6230ac9329d2ad4a8723a4751 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 23 Feb 2018 14:21:05 +0100 Subject: [PATCH 1/6] Remove unnecessary "list" typedef from wxList iterators This typedef was simply never used and, as it was private, removing it shouldn't result in any compatibility problems. --- include/wx/list.h | 4 ---- 1 file changed, 4 deletions(-) diff --git a/include/wx/list.h b/include/wx/list.h index 427c0392f639..e370c2885b5d 100644 --- a/include/wx/list.h +++ b/include/wx/list.h @@ -761,7 +761,6 @@ friend class wxHashTableBase; // should be able to call untyped Find() \ classexp iterator \ { \ - typedef name list; \ public: \ typedef nodetype Node; \ typedef iterator itor; \ @@ -811,7 +810,6 @@ friend class wxHashTableBase; // should be able to call untyped Find() }; \ classexp const_iterator \ { \ - typedef name list; \ public: \ typedef nodetype Node; \ typedef T* value_type; \ @@ -864,7 +862,6 @@ friend class wxHashTableBase; // should be able to call untyped Find() }; \ classexp reverse_iterator \ { \ - typedef name list; \ public: \ typedef nodetype Node; \ typedef T* value_type; \ @@ -903,7 +900,6 @@ friend class wxHashTableBase; // should be able to call untyped Find() }; \ classexp const_reverse_iterator \ { \ - typedef name list; \ public: \ typedef nodetype Node; \ typedef T* value_type; \ From fdbe357e4b3a9f2c2ec658b047232d7f6d30f709 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 23 Feb 2018 15:47:12 +0100 Subject: [PATCH 2/6] Make wxList iterators conform to input iterator requirements Define "pointer", "reference", "difference_type" and "iterator_category" typedefs to ensure that wxList iterator classes are seen as iterators by the standard library in C++11 and later, as otherwise standard container template ctors taking iterators couldn't be used with them because they're only available if input iterator requirements are satisfied. This notably fixes creation of std::list from wxList iterators; add a test which didn't compile before to show it. --- docs/changes.txt | 8 ++++++++ include/wx/list.h | 38 ++++++++++++++++++++++++++++++++------ tests/lists/lists.cpp | 24 ++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 6 deletions(-) diff --git a/docs/changes.txt b/docs/changes.txt index 7fc8529dd027..7f91d492bb46 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -64,6 +64,14 @@ Changes in behaviour which may result in build errors wxGraphicsContext::CreatePen() continues to compile and work as before. +3.1.2: (released 2018-??-??) +---------------------------- + +All: + +- Make wxList iterators conform to input iterator requirements. + + 3.1.1: (released 2018-02-19) ---------------------------- diff --git a/include/wx/list.h b/include/wx/list.h index e370c2885b5d..7cd5205d904a 100644 --- a/include/wx/list.h +++ b/include/wx/list.h @@ -599,6 +599,17 @@ friend class wxHashTableBase; // should be able to call untyped Find() // macros for definition of "template" list type // ----------------------------------------------------------------------------- +// Helper macro defining common iterator typedefs +#if wxUSE_STD_CONTAINERS_COMPATIBLY + #include + + #define WX_DECLARE_LIST_ITER_DIFF_AND_CATEGORY() \ + typedef std::ptrdiff_t difference_type; \ + typedef std::bidirectional_iterator_tag iterator_category; +#else + #define WX_DECLARE_LIST_ITER_DIFF_AND_CATEGORY() +#endif + // and now some heavy magic... // declare a list type named 'name' and containing elements of type 'T *' @@ -762,15 +773,19 @@ friend class wxHashTableBase; // should be able to call untyped Find() classexp iterator \ { \ public: \ + WX_DECLARE_LIST_ITER_DIFF_AND_CATEGORY() \ + typedef T* value_type; \ + typedef value_type* pointer; \ + typedef value_type& reference; \ + \ typedef nodetype Node; \ typedef iterator itor; \ - typedef T* value_type; \ typedef value_type* ptr_type; \ - typedef value_type& reference; \ \ Node* m_node; \ Node* m_init; \ public: \ + /* Compatibility typedefs, don't use */ \ typedef reference reference_type; \ typedef ptr_type pointer_type; \ \ @@ -811,8 +826,12 @@ friend class wxHashTableBase; // should be able to call untyped Find() classexp const_iterator \ { \ public: \ - typedef nodetype Node; \ + WX_DECLARE_LIST_ITER_DIFF_AND_CATEGORY() \ typedef T* value_type; \ + typedef const value_type* pointer; \ + typedef const value_type& reference; \ + \ + typedef nodetype Node; \ typedef const value_type& const_reference; \ typedef const_iterator itor; \ typedef value_type* ptr_type; \ @@ -863,11 +882,14 @@ friend class wxHashTableBase; // should be able to call untyped Find() classexp reverse_iterator \ { \ public: \ - typedef nodetype Node; \ + WX_DECLARE_LIST_ITER_DIFF_AND_CATEGORY() \ typedef T* value_type; \ + typedef value_type* pointer; \ + typedef value_type& reference; \ + \ + typedef nodetype Node; \ typedef reverse_iterator itor; \ typedef value_type* ptr_type; \ - typedef value_type& reference; \ \ Node* m_node; \ Node* m_init; \ @@ -901,8 +923,12 @@ friend class wxHashTableBase; // should be able to call untyped Find() classexp const_reverse_iterator \ { \ public: \ - typedef nodetype Node; \ + WX_DECLARE_LIST_ITER_DIFF_AND_CATEGORY() \ typedef T* value_type; \ + typedef const value_type* pointer; \ + typedef const value_type& reference; \ + \ + typedef nodetype Node; \ typedef const_reverse_iterator itor; \ typedef value_type* ptr_type; \ typedef const value_type& const_reference; \ diff --git a/tests/lists/lists.cpp b/tests/lists/lists.cpp index f4b1e3472dce..d19376e7dd4f 100644 --- a/tests/lists/lists.cpp +++ b/tests/lists/lists.cpp @@ -210,3 +210,27 @@ void ListsTestCase::wxListCtorTest() CPPUNIT_ASSERT( Baz::GetNumber() == 0 ); } +#if wxUSE_STD_CONTAINERS_COMPATIBLY + +#include + +// Check that we convert wxList to std::list using the latter's ctor taking 2 +// iterators: this used to be broken in C++11 because wxList iterators didn't +// fully implement input iterator requirements. +TEST_CASE("wxList::iterator", "[list][std][iterator]") +{ + Baz baz1("one"), + baz2("two"); + + wxListBazs li; + li.push_back(&baz1); + li.push_back(&baz2); + + std::list stdli(li.begin(), li.end()); + CHECK( stdli.size() == 2 ); + + const wxListBazs cli; + CHECK( std::list(cli.begin(), cli.end()).empty() ); +} + +#endif // wxUSE_STD_CONTAINERS_COMPATIBLY From 9edf06794e09427c0f1b8647e0eee154f45ab6c5 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 23 Feb 2018 16:00:42 +0100 Subject: [PATCH 3/6] Remove ptr_type typedef from wxList iterator classes This typedef is completely redundant with pointer_type which had been also available in these classes since the very beginning and seems to have been meant to be private originally, so it should be safe to just remove it, especially because I couldn't find any existing code using it. If we do find such code in the wild later, this commit could be reverted as it's not really indispensable. --- include/wx/list.h | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/include/wx/list.h b/include/wx/list.h index 7cd5205d904a..8b67ccbd88bc 100644 --- a/include/wx/list.h +++ b/include/wx/list.h @@ -780,14 +780,13 @@ friend class wxHashTableBase; // should be able to call untyped Find() \ typedef nodetype Node; \ typedef iterator itor; \ - typedef value_type* ptr_type; \ \ Node* m_node; \ Node* m_init; \ public: \ /* Compatibility typedefs, don't use */ \ typedef reference reference_type; \ - typedef ptr_type pointer_type; \ + typedef pointer pointer_type; \ \ iterator(Node* node, Node* init) : m_node(node), m_init(init) {}\ iterator() : m_node(NULL), m_init(NULL) { } \ @@ -834,13 +833,12 @@ friend class wxHashTableBase; // should be able to call untyped Find() typedef nodetype Node; \ typedef const value_type& const_reference; \ typedef const_iterator itor; \ - typedef value_type* ptr_type; \ \ Node* m_node; \ Node* m_init; \ public: \ - typedef const_reference reference_type; \ - typedef const ptr_type pointer_type; \ + typedef reference reference_type; \ + typedef pointer pointer_type; \ \ const_iterator(Node* node, Node* init) \ : m_node(node), m_init(init) { } \ @@ -889,13 +887,12 @@ friend class wxHashTableBase; // should be able to call untyped Find() \ typedef nodetype Node; \ typedef reverse_iterator itor; \ - typedef value_type* ptr_type; \ \ Node* m_node; \ Node* m_init; \ public: \ typedef reference reference_type; \ - typedef ptr_type pointer_type; \ + typedef pointer pointer_type; \ \ reverse_iterator(Node* node, Node* init) \ : m_node(node), m_init(init) { } \ @@ -930,14 +927,13 @@ friend class wxHashTableBase; // should be able to call untyped Find() \ typedef nodetype Node; \ typedef const_reverse_iterator itor; \ - typedef value_type* ptr_type; \ typedef const value_type& const_reference; \ \ Node* m_node; \ Node* m_init; \ public: \ - typedef const_reference reference_type; \ - typedef const ptr_type pointer_type; \ + typedef reference reference_type; \ + typedef pointer pointer_type; \ \ const_reverse_iterator(Node* node, Node* init) \ : m_node(node), m_init(init) { } \ From 7e0ca8357e6e1d04fcd25ab32cbe8ca35ddf0579 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 23 Feb 2018 16:03:36 +0100 Subject: [PATCH 4/6] Also remove wxList::const_iterator::const_reference typedef This typedef is redundant with the "reference" one and doesn't seem to be used anywhere. As with the previous commit, this one could be reverted later if it turns out it does break any existing code, but this seems unlikely. --- include/wx/list.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/include/wx/list.h b/include/wx/list.h index 8b67ccbd88bc..22446a2dd460 100644 --- a/include/wx/list.h +++ b/include/wx/list.h @@ -831,7 +831,6 @@ friend class wxHashTableBase; // should be able to call untyped Find() typedef const value_type& reference; \ \ typedef nodetype Node; \ - typedef const value_type& const_reference; \ typedef const_iterator itor; \ \ Node* m_node; \ @@ -927,7 +926,6 @@ friend class wxHashTableBase; // should be able to call untyped Find() \ typedef nodetype Node; \ typedef const_reverse_iterator itor; \ - typedef const value_type& const_reference; \ \ Node* m_node; \ Node* m_init; \ From 382a5a156e2f638e4b2414b5d34231ad296dad86 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 23 Feb 2018 16:10:07 +0100 Subject: [PATCH 5/6] Use ptrdiff_t as wxVector::difference_type instead of size_t difference_type must be signed, using size_t was clearly a mistake. --- include/wx/vector.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/wx/vector.h b/include/wx/vector.h index e73b1b9514e5..49b0840c9f6a 100644 --- a/include/wx/vector.h +++ b/include/wx/vector.h @@ -160,7 +160,7 @@ class wxVector public: typedef size_t size_type; - typedef size_t difference_type; + typedef ptrdiff_t difference_type; typedef T value_type; typedef value_type* pointer; typedef const value_type* const_pointer; From cc8fccf0bcb445cf8a699fa6a5e3977b9bb516a0 Mon Sep 17 00:00:00 2001 From: Vadim Zeitlin Date: Fri, 23 Feb 2018 16:14:03 +0100 Subject: [PATCH 6/6] Make wxVector reverse iterators conform to iterator requirements This is similar to a recent commit adding the missing typedefs to wxList iterators and defines the types required by the iterator concept in wxVector::reverse_iterator and const_reverse_iterator classes (simple iterators are just pointers and are already covered by the standard iterator_traits specialization). --- docs/changes.txt | 2 +- include/wx/vector.h | 19 +++++++++++++++++++ tests/vectors/vectors.cpp | 11 +++++++++++ 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/docs/changes.txt b/docs/changes.txt index 7f91d492bb46..f4867d6ac6fe 100644 --- a/docs/changes.txt +++ b/docs/changes.txt @@ -69,7 +69,7 @@ Changes in behaviour which may result in build errors All: -- Make wxList iterators conform to input iterator requirements. +- Make wxList and wxVector iterators conform to input iterator requirements. 3.1.1: (released 2018-02-19) diff --git a/include/wx/vector.h b/include/wx/vector.h index 49b0840c9f6a..8a7ae1b22813 100644 --- a/include/wx/vector.h +++ b/include/wx/vector.h @@ -33,6 +33,9 @@ inline void wxVectorSort(wxVector& v) #include "wx/meta/if.h" #include "wx/beforestd.h" +#if wxUSE_STD_CONTAINERS_COMPATIBLY +#include +#endif #include // for placement new #include "wx/afterstd.h" @@ -172,6 +175,14 @@ class wxVector class reverse_iterator { public: +#if wxUSE_STD_CONTAINERS_COMPATIBLY + typedef std::random_access_iterator_tag iterator_category; +#endif + typedef ptrdiff_t difference_type; + typedef T value_type; + typedef value_type* pointer; + typedef value_type& reference; + reverse_iterator() : m_ptr(NULL) { } explicit reverse_iterator(iterator it) : m_ptr(it) { } reverse_iterator(const reverse_iterator& it) : m_ptr(it.m_ptr) { } @@ -218,6 +229,14 @@ class wxVector class const_reverse_iterator { public: +#if wxUSE_STD_CONTAINERS_COMPATIBLY + typedef std::random_access_iterator_tag iterator_category; +#endif + typedef ptrdiff_t difference_type; + typedef T value_type; + typedef const value_type* pointer; + typedef const value_type& reference; + const_reverse_iterator() : m_ptr(NULL) { } explicit const_reverse_iterator(const_iterator it) : m_ptr(it) { } const_reverse_iterator(const reverse_iterator& it) : m_ptr(it.m_ptr) { } diff --git a/tests/vectors/vectors.cpp b/tests/vectors/vectors.cpp index 25a9a5cdd596..e3f6734c14c4 100644 --- a/tests/vectors/vectors.cpp +++ b/tests/vectors/vectors.cpp @@ -22,6 +22,10 @@ #include "wx/vector.h" +#if wxUSE_STD_CONTAINERS_COMPATIBLY + #include +#endif // wxUSE_STD_CONTAINERS_COMPATIBLY + // ---------------------------------------------------------------------------- // simple class capable of detecting leaks of its objects // ---------------------------------------------------------------------------- @@ -360,6 +364,13 @@ TEST_CASE("wxVector::reverse_iterator", "[vector][reverse_iterator]") ri = rb + 2; CHECK( ri - rb == 2 ); CHECK( re - ri == 8 ); + +#if wxUSE_STD_CONTAINERS_COMPATIBLY + std::vector stdvec(rb, re); + REQUIRE( stdvec.size() == 10 ); + CHECK( stdvec[0] == 10 ); + CHECK( stdvec[9] == 1 ); +#endif // wxUSE_STD_CONTAINERS_COMPATIBLY } TEST_CASE("wxVector::capacity", "[vector][capacity][shrink_to_fit]")