diff --git a/include/wx/vector.h b/include/wx/vector.h index 594a43cc58..aa74c6586e 100644 --- a/include/wx/vector.h +++ b/include/wx/vector.h @@ -113,6 +113,34 @@ struct wxVectorMemOpsGeneric } }; +// We need to distinguish integers from iterators in assign() overloads and the +// simplest way to do it would be by using std::iterator_traits<>, however this +// might break existing code using custom iterator classes but not specializing +// iterator_traits<> for them, so we approach the problem from the other end +// and use our own traits that we specialize for all integer types. + +struct IsIntType {}; +struct IsNotIntType {}; + +template struct IsInt : IsNotIntType {}; + +#define WX_DECLARE_TYPE_IS_INT(type) \ + template <> struct IsInt : IsIntType {} + +WX_DECLARE_TYPE_IS_INT(unsigned char); +WX_DECLARE_TYPE_IS_INT(signed char); +WX_DECLARE_TYPE_IS_INT(unsigned short int); +WX_DECLARE_TYPE_IS_INT(signed short int); +WX_DECLARE_TYPE_IS_INT(unsigned int); +WX_DECLARE_TYPE_IS_INT(signed int); +WX_DECLARE_TYPE_IS_INT(unsigned long int); +WX_DECLARE_TYPE_IS_INT(signed long int); +#ifdef wxLongLong_t +WX_DECLARE_TYPE_IS_INT(wxLongLong_t); +WX_DECLARE_TYPE_IS_INT(wxULongLong_t); +#endif + +#undef WX_DECLARE_TYPE_IS_INT } // namespace wxPrivate @@ -269,23 +297,13 @@ public: void assign(size_type p_size, const value_type& v) { - clear(); - reserve(p_size); - for ( size_t n = 0; n < p_size; n++ ) - push_back(v); + AssignFromValue(p_size, v); } - template + template void assign(InputIterator first, InputIterator last) { - clear(); - - // Notice that it would be nice to call reserve() here but we can't do - // it for arbitrary input iterators, we should have a dispatch on - // iterator type and call it if possible. - - for ( InputIterator it = first; it != last; ++it ) - push_back(*it); + AssignDispatch(first, last, typename wxPrivate::IsInt()); } void swap(wxVector& v) @@ -545,6 +563,36 @@ private: push_back(v); } + void AssignFromValue(size_type p_size, const value_type& v) + { + clear(); + reserve(p_size); + for ( size_t n = 0; n < p_size; n++ ) + push_back(v); + } + + template + void AssignDispatch(InputIterator first, InputIterator last, + wxPrivate::IsIntType) + { + AssignFromValue(static_cast(first), + static_cast(last)); + } + + template + void AssignDispatch(InputIterator first, InputIterator last, + wxPrivate::IsNotIntType) + { + clear(); + + // Notice that it would be nice to call reserve() here but we can't do + // it for arbitrary input iterators, we should have a dispatch on + // iterator type and call it if possible. + + for ( InputIterator it = first; it != last; ++it ) + push_back(*it); + } + size_type m_size, m_capacity; value_type *m_values;