This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
Re: [Patch] First bits of the algo merge
On Dec 14, 2005, at 10:51 AM, Howard Hinnant wrote:
That proxy test is still on the way...
Ok, below is a test. It isn't a testsuite test, though it could be
made into one. Rather it is a self contained HelloWorld that makes
it easy to experiment. It has both equal_to approaches, labeled by
METHOD A and B. #define METHOD to switch techniques. A proxy
iterator was quickly cobbled together from an earlier (unrelated)
experiment. And I looked for the simplest std::algorithm I could
find which exercises this issue and chose equal.
#define A 0
#define B 1
#define METHOD A
#if METHOD == A
struct equal_to
{
template <class _Lhs, class _Rhs>
bool operator()(const _Lhs& __lhs, const _Lhs& __rhs) const
{return __lhs == __rhs;}
};
#elif METHOD == B
template <class _Lhs, class _Rhs = _Lhs>
struct equal_to
{
bool operator()(const _Lhs& __lhs, const _Lhs& __rhs) const
{return __lhs == __rhs;}
bool operator()(const _Lhs& __lhs, const _Rhs& __rhs) const
{return __lhs == __rhs;}
bool operator()(const _Rhs& __lhs, const _Lhs& __rhs) const
{return __lhs == __rhs;}
bool operator()(const _Rhs& __lhs, const _Rhs& __rhs) const
{return __lhs == __rhs;}
};
template <class _Lhs>
struct equal_to<_Lhs, _Lhs>
{
bool operator()(const _Lhs& __lhs, const _Lhs& __rhs) const
{return __lhs == __rhs;}
};
#endif
#include <iterator>
template <class InputIterator1, class InputIterator2, class
BinaryPredicate>
inline
bool
equal(InputIterator1 first1, InputIterator1 last1,
InputIterator2 first2, BinaryPredicate pred)
{
for (; first1 != last1; ++first1, ++first2)
if (!pred(*first1, *first2))
return false;
return true;
}
template <class InputIterator1, class InputIterator2>
inline
bool
equal(InputIterator1 first1, InputIterator1 last1, InputIterator2
first2)
{
typedef typename
std::iterator_traits<InputIterator1>::value_type value_type1;
typedef typename
std::iterator_traits<InputIterator2>::value_type value_type2;
#if METHOD == A
return ::equal(first1, last1, first2, equal_to());
#elif METHOD == B
return ::equal(first1, last1, first2, equal_to<value_type1,
value_type2>());
#endif
}
#include <iostream>
#include <iterator>
#include <cstddef>
template <typename T>
class iterator
{
class proxy
{
friend class iterator;
iterator* const iter_;
explicit proxy(iterator* iter) : iter_(iter) {}
public:
operator T& () const {return iter_->dirty_deref();}
operator const T& () {return iter_->deref();}
T* operator-> () const {return &iter_->dirty_deref();}
const T* operator-> () {return &iter_->deref();}
T& operator= (const T& rh) {return iter_->dirty_deref() = rh;}
};
public:
typedef T value_type;
typedef std::ptrdiff_t difference_type;
typedef proxy pointer;
typedef proxy reference;
typedef std::random_access_iterator_tag iterator_category;
private:
T* ptr_;
bool dirty_;
T& dirty_deref() {dirty_ = true; return *ptr_;}
const T& deref() {return *ptr_;}
public:
iterator(T* v) : ptr_(v), dirty_(false) {}
bool is_dirty() const {return dirty_;}
void reset_dirty() {dirty_ = false;}
T* base() const {return ptr_;}
proxy operator*() {return proxy(this);}
proxy operator->() {return proxy(this);}
const proxy operator->() const {return proxy
(const_cast<iterator*>(this));}
iterator& operator++() {++ptr_; return *this;}
iterator operator++(int) {iterator tmp(*this); operator++();
return tmp;}
iterator& operator--() {--ptr_; return *this;}
iterator operator--(int) {iterator tmp(*this); operator--();
return tmp;}
iterator& operator+=(difference_type n) {ptr_ += n; return *this;}
iterator operator+(difference_type n) const {return iterator
(*this) += n;}
reference operator [] (difference_type i) const {return *(*this
+ i);}
iterator& operator-=(difference_type n) {return operator+=(-n);}
iterator operator-(difference_type n) const {return iterator
(*this) -= n;}
};
template <class T>
inline
iterator<T>
operator + (typename iterator<T>::difference_type n, const
iterator<T>& y)
{
return iterator<T>(y) += n;
}
template <class T>
inline
typename iterator<T>::difference_type
operator -(const iterator<T>& x, const iterator<T>& y)
{
return x.base() - y.base();
}
template <class T>
inline
bool
operator ==(const iterator<T>& x, const iterator<T>& y)
{
return x.base() == y.base();
}
template <class T>
inline
bool
operator !=(const iterator<T>& x, const iterator<T>& y)
{
return !(x == y);
}
template <class T>
inline
bool
operator <(const iterator<T>& x, const iterator<T>& y)
{
return x.base() < y.base();
}
template <class T>
inline
bool
operator >(const iterator<T>& x, const iterator<T>& y)
{
return y < x;
}
template <class T>
inline
bool
operator <=(const iterator<T>& x, const iterator<T>& y)
{
return !(y < x);
}
template <class T>
inline
bool
operator >=(const iterator<T>& x, const iterator<T>& y)
{
return !(x < y);
}
int main()
{
int array[] = {1, 2, 3};
iterator<int> begin(array);
iterator<int> end(array + sizeof(array)/sizeof(array[0]));
std::cout << equal(begin, end, begin) << '\n';
}
With METHOD A I get:
main.cpp:42: error: no match for call to '(equal_to)
(iterator<int>::proxy, iterator<int>::proxy)'
With METHOD B I get it to compile and print out:
1
Hope this helps.
-Howard