diff --git a/include/wx/generic/grid.h b/include/wx/generic/grid.h index b41b8a9829..762c4e099d 100644 --- a/include/wx/generic/grid.h +++ b/include/wx/generic/grid.h @@ -19,6 +19,10 @@ #include "wx/scrolwin.h" +#if wxUSE_STD_CONTAINERS_COMPATIBLY + #include +#endif + // ---------------------------------------------------------------------------- // constants // ---------------------------------------------------------------------------- @@ -869,40 +873,45 @@ struct wxGridBlockDiffResult }; // ---------------------------------------------------------------------------- -// wxGridSelectionRange: the range of grid selection blocks +// wxGridSelectionRange: a range of grid blocks that can be iterated over // ---------------------------------------------------------------------------- class wxGridSelectionRange { + typedef wxVector::const_iterator iterator_impl; + public: - typedef wxVector::const_iterator iterator; - - wxGridSelectionRange() : - m_begin(), - m_end(), - m_it() + class iterator { - } + public: +#if wxUSE_STD_CONTAINERS_COMPATIBLY + typedef std::forward_iterator_tag iterator_category; +#endif + typedef ptrdiff_t difference_type; + typedef wxGridBlockCoords value_type; + typedef const value_type& reference; - // Get the current selection block coordinates. - const wxGridBlockCoords& GetBlockCoords() const - { - static wxGridBlockCoords empty; - return Valid() ? *m_it : empty; - } + iterator() : m_it() { } - // Iterate to the next block. - void Next() - { - if ( Valid() ) - ++m_it; - } + reference operator*() const { return *m_it; } - // Whether the iterator is valid. - bool Valid() const - { - return m_it != m_end; - } + iterator& operator++() + { ++m_it; return *this; } + iterator operator++(int) + { iterator tmp = *this; ++m_it; return tmp; } + + bool operator==(const iterator& it) const + { return m_it == it.m_it; } + bool operator!=(const iterator& it) const + { return m_it != it.m_it; } + + private: + explicit iterator(iterator_impl it) : m_it(it) { } + + iterator_impl m_it; + + friend class wxGridSelectionRange; + }; iterator begin() const { @@ -915,16 +924,20 @@ public: } private: - wxGridSelectionRange(iterator begin, iterator end) : + wxGridSelectionRange() : + m_begin(), + m_end() + { + } + + wxGridSelectionRange(iterator_impl begin, iterator_impl end) : m_begin(begin), - m_end(end), - m_it(begin) + m_end(end) { } const iterator m_begin; const iterator m_end; - iterator m_it; friend class wxGrid; }; diff --git a/interface/wx/grid.h b/interface/wx/grid.h index dc17b2b9ae..1976ff27da 100644 --- a/interface/wx/grid.h +++ b/interface/wx/grid.h @@ -2006,7 +2006,29 @@ struct wxGridBlockDiffResult }; /** - The range of grid selection blocks. + Represents a range of grid blocks that can be iterated over. + + This class provides read-only access to the blocks making up the grid + selection in the most general case. + + Note that objects of this class can only be returned by wxGrid, but not + constructed in the application code. + + The preferable way to iterate over it is using C++11 range-for loop: + @code + for ( const auto block: grid->GetSelectionRange() ) { + ... do something with block ... + } + @endcode + When not using C++11, iteration has to be done manually: + @code + wxGridSelectionRange range = grid->GetSelectionRange(); + for ( wxGridSelectionRange::iterator it = range.begin(); + it != range.end(); + ++it ) { + ... do something with *it ... + } + @endcode @since 3.1.4 */ @@ -2014,34 +2036,30 @@ class wxGridSelectionRange { public: /** - Default constructor initializes the iterator. - */ - wxGridSelectionRange(); + Read-only forward iterator type. - /** - * Get the current selection block coordinates. + This is an opaque type, which satisfies the forward iterator + requirements, i.e. provides all the expected operations, such as + comparison, dereference and pre- and post-increment. */ - const wxGridBlockCoords& GetBlockCoords() const; + class iterator + { + iterator(); - /** - * Iterate to the next block. - */ - void Next(); + const wxGridBlockCoords& operator*() const; - /** - * Whether the iterator is valid. - */ - bool Valid(); + iterator& operator++(); + iterator operator++(int); - /** - * The function to allow using range-based for. - */ - wxGridBlockCoords *begin() const; + bool operator==(const iterator& it) const; + bool operator!=(const iterator& it) const; + }; - /** - * The function to allow using range-based for. - */ - wxGridBlockCoords *end() const; + /// Return iterator corresponding to the beginning of the range. + iterator begin() const; + + /// Return iterator corresponding to the end of the range. + iterator end() const; }; /** @@ -4648,7 +4666,15 @@ public: void DeselectCell( int row, int col ); /** - Returns an range of grid selection blocks. + Returns a range of grid selection blocks. + + The returned range can be iterated over, e.g. with C++11 range-for loop: + @code + for ( const auto block: grid->GetSelectionRange() ) { + if ( block.Intersects(myBlock) ) + break; + } + @endcode @since 3.1.4 */ diff --git a/tests/controls/gridtest.cpp b/tests/controls/gridtest.cpp index 82fac33040..d32e94e955 100644 --- a/tests/controls/gridtest.cpp +++ b/tests/controls/gridtest.cpp @@ -524,18 +524,16 @@ TEST_CASE_METHOD(GridTestCase, "Grid::Selection", "[grid]") CHECK(!m_grid->IsInSelection(3, 0)); } -TEST_CASE_METHOD(GridTestCase, "Grid::SelectionIterator", "[grid]") +TEST_CASE_METHOD(GridTestCase, "Grid::SelectionRange", "[grid]") { - CHECK(!m_grid->GetSelectionRange().Valid()); + const wxGridSelectionRange empty = m_grid->GetSelectionRange(); + CHECK( empty.begin() == empty.end() ); m_grid->SelectBlock(1, 0, 3, 1); wxGridSelectionRange sel = m_grid->GetSelectionRange(); - CHECK(sel.Valid()); - CHECK(sel.GetBlockCoords() == wxGridBlockCoords(1, 0, 3, 1)); - - sel.Next(); - CHECK(!sel.Valid()); + REQUIRE( sel.begin() != sel.end() ); + CHECK( *sel.begin() == wxGridBlockCoords(1, 0, 3, 1) ); #if __cplusplus >= 201103L || wxCHECK_VISUALC_VERSION(10) m_grid->SelectBlock(4, 0, 7, 1, true);