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.
This commit is contained in:
@@ -64,6 +64,14 @@ Changes in behaviour which may result in build errors
|
|||||||
wxGraphicsContext::CreatePen() continues to compile and work as before.
|
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)
|
3.1.1: (released 2018-02-19)
|
||||||
----------------------------
|
----------------------------
|
||||||
|
|
||||||
|
@@ -599,6 +599,17 @@ private:
|
|||||||
// macros for definition of "template" list type
|
// macros for definition of "template" list type
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Helper macro defining common iterator typedefs
|
||||||
|
#if wxUSE_STD_CONTAINERS_COMPATIBLY
|
||||||
|
#include <iterator>
|
||||||
|
|
||||||
|
#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...
|
// and now some heavy magic...
|
||||||
|
|
||||||
// declare a list type named 'name' and containing elements of type 'T *'
|
// declare a list type named 'name' and containing elements of type 'T *'
|
||||||
@@ -762,15 +773,19 @@ private:
|
|||||||
classexp iterator \
|
classexp iterator \
|
||||||
{ \
|
{ \
|
||||||
public: \
|
public: \
|
||||||
|
WX_DECLARE_LIST_ITER_DIFF_AND_CATEGORY() \
|
||||||
|
typedef T* value_type; \
|
||||||
|
typedef value_type* pointer; \
|
||||||
|
typedef value_type& reference; \
|
||||||
|
\
|
||||||
typedef nodetype Node; \
|
typedef nodetype Node; \
|
||||||
typedef iterator itor; \
|
typedef iterator itor; \
|
||||||
typedef T* value_type; \
|
|
||||||
typedef value_type* ptr_type; \
|
typedef value_type* ptr_type; \
|
||||||
typedef value_type& reference; \
|
|
||||||
\
|
\
|
||||||
Node* m_node; \
|
Node* m_node; \
|
||||||
Node* m_init; \
|
Node* m_init; \
|
||||||
public: \
|
public: \
|
||||||
|
/* Compatibility typedefs, don't use */ \
|
||||||
typedef reference reference_type; \
|
typedef reference reference_type; \
|
||||||
typedef ptr_type pointer_type; \
|
typedef ptr_type pointer_type; \
|
||||||
\
|
\
|
||||||
@@ -811,8 +826,12 @@ private:
|
|||||||
classexp const_iterator \
|
classexp const_iterator \
|
||||||
{ \
|
{ \
|
||||||
public: \
|
public: \
|
||||||
typedef nodetype Node; \
|
WX_DECLARE_LIST_ITER_DIFF_AND_CATEGORY() \
|
||||||
typedef T* value_type; \
|
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 value_type& const_reference; \
|
||||||
typedef const_iterator itor; \
|
typedef const_iterator itor; \
|
||||||
typedef value_type* ptr_type; \
|
typedef value_type* ptr_type; \
|
||||||
@@ -863,11 +882,14 @@ private:
|
|||||||
classexp reverse_iterator \
|
classexp reverse_iterator \
|
||||||
{ \
|
{ \
|
||||||
public: \
|
public: \
|
||||||
typedef nodetype Node; \
|
WX_DECLARE_LIST_ITER_DIFF_AND_CATEGORY() \
|
||||||
typedef T* value_type; \
|
typedef T* value_type; \
|
||||||
|
typedef value_type* pointer; \
|
||||||
|
typedef value_type& reference; \
|
||||||
|
\
|
||||||
|
typedef nodetype Node; \
|
||||||
typedef reverse_iterator itor; \
|
typedef reverse_iterator itor; \
|
||||||
typedef value_type* ptr_type; \
|
typedef value_type* ptr_type; \
|
||||||
typedef value_type& reference; \
|
|
||||||
\
|
\
|
||||||
Node* m_node; \
|
Node* m_node; \
|
||||||
Node* m_init; \
|
Node* m_init; \
|
||||||
@@ -901,8 +923,12 @@ private:
|
|||||||
classexp const_reverse_iterator \
|
classexp const_reverse_iterator \
|
||||||
{ \
|
{ \
|
||||||
public: \
|
public: \
|
||||||
typedef nodetype Node; \
|
WX_DECLARE_LIST_ITER_DIFF_AND_CATEGORY() \
|
||||||
typedef T* value_type; \
|
typedef T* value_type; \
|
||||||
|
typedef const value_type* pointer; \
|
||||||
|
typedef const value_type& reference; \
|
||||||
|
\
|
||||||
|
typedef nodetype Node; \
|
||||||
typedef const_reverse_iterator itor; \
|
typedef const_reverse_iterator itor; \
|
||||||
typedef value_type* ptr_type; \
|
typedef value_type* ptr_type; \
|
||||||
typedef const value_type& const_reference; \
|
typedef const value_type& const_reference; \
|
||||||
|
@@ -210,3 +210,27 @@ void ListsTestCase::wxListCtorTest()
|
|||||||
CPPUNIT_ASSERT( Baz::GetNumber() == 0 );
|
CPPUNIT_ASSERT( Baz::GetNumber() == 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if wxUSE_STD_CONTAINERS_COMPATIBLY
|
||||||
|
|
||||||
|
#include <list>
|
||||||
|
|
||||||
|
// 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<Baz*> stdli(li.begin(), li.end());
|
||||||
|
CHECK( stdli.size() == 2 );
|
||||||
|
|
||||||
|
const wxListBazs cli;
|
||||||
|
CHECK( std::list<Baz*>(cli.begin(), cli.end()).empty() );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // wxUSE_STD_CONTAINERS_COMPATIBLY
|
||||||
|
Reference in New Issue
Block a user