Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

iterator_pair for std::mismatch

7 views
Skip to first unread message

Krzysztof Żelechowski

unread,
Sep 4, 2011, 3:24:16 PM9/4/11
to
/* iterator_pair */
/*
* Provides support for calling mismatch with arbitrary input iterators.
* This support is missing from the standard library. <URL:
news:j3oo43$2ti2$1...@news2.ipartners.pl >
* The unit test contains sample code. */

#define MY_ this ->
#include <algorithm>

#ifdef SINGLE_TEST
#define UNIT_TEST
#endif

#ifdef UNIT_TEST
#include <cstdlib>
#include <cassert>
#include <sstream>
#endif
namespace x { enum { RANGE_BEGIN, RANGE_END, RANGE_COUNT };
template < class P_I1, class P_I2 > struct iterator_pair_traits
{
public: typedef P_I1 first; public: typedef P_I2 second;
public: typedef std:: pair < first, second >
representation;
public: typedef std:: pair < std:: iterator_traits < first
>, std:: iterator_traits < second > > traits;
public:
typedef std:: pair < typename traits:: first_type::
value_type, typename traits:: second_type:: value_type > value_type;
public: typedef std:: iterator < typename std::
iterator_traits < first >:: iterator_category, value_type > declaration;
};
template < class P_I1, class P_I2 >
struct iterator_pair_with:
protected iterator_pair_traits < P_I1, P_I2 >:: representation,
public iterator_pair_traits < P_I1, P_I2 >:: declaration
{
public: typedef iterator_pair_with self, &ref;
public: typedef self const cref;
public: typedef P_I1 first_iterator;
public: typedef P_I2 second_iterator;
public: typedef std:: pair < self:: first_iterator, self::
second_iterator > representation;
public: typedef typename iterator_pair_traits <
first_iterator, second_iterator >:: declaration declaration;
public: using representation:: first;
public: using representation:: second;
public: iterator_pair_with (P_I1 const &p_i1, P_I2 const
&p_i2): representation (p_i1, p_i2) { }
public: typename self:: value_type operator * (void) const
{ return typename self:: value_type (*MY_ first, *MY_ second); }
public: ref operator ++ (void) { ++MY_ first; ++MY_
second; return *this; }
public: int operator != (cref that) { return MY_ first !=
that. first && MY_ second != that. second; }
public: static int do_compare (typename self:: value_type
const &p_v) { return p_v. first != p_v. second; };
};
template < class P_I1, class P_I2 >
static inline x:: iterator_pair_with < P_I1, P_I2 > iterator_pair
(P_I1 const & p_i1, P_I2 const &p_i2)
{ return iterator_pair_with < P_I1, P_I2 > (p_i1, p_i2); }
namespace impl { template <class P_T >
static inline P_T
mismatch (P_T const p_z [+RANGE_COUNT])
{
return std:: find_if (*p_z, p_z [01], P_T:: do_compare); }
template < class P_I1, class P_I2, class P_Z >
static inline iterator_pair_with < P_I1, P_I2 >
mismatch
(P_I1 const p_i1 [+RANGE_COUNT], P_I2 const p_i2 [+RANGE_COUNT],
P_Z const &p_z)
{
P_Z const
l_zip [+RANGE_COUNT] =
{
p_z,
iterator_pair (p_i1 [01], p_i2 [01])
};
return (mismatch (l_zip));
}
}
template < class P_I1, class P_I2 >
static inline iterator_pair_with < P_I1, P_I2 > mismatch (P_I1
const p_i1 [+RANGE_COUNT], P_I2 const p_i2 [+RANGE_COUNT])
{ return impl:: mismatch (p_i1, p_i2, iterator_pair (*p_i1,
*p_i2)); }

#ifdef UNIT_TEST
namespace test {
template < class P_C >
static int iterator_pair (int p_argc, P_C const *const p_argv [])
{
for (int an_ix ((01)); +an_ix < +p_argc; ++an_ix)
{
P_C const *const
l_s_rg [+RANGE_COUNT] = { p_argv [+an_ix], p_argv [+an_ix] + std::
char_traits < char >:: length (p_argv [+an_ix]) };
std:: istringstream a_s ((l_s_rg [+RANGE_BEGIN]));
std:: istreambuf_iterator < P_C > const l_i_rg [+RANGE_COUNT] = { std::
istreambuf_iterator < P_C > (a_s) };
assert (x:: mismatch (l_i_rg, l_s_rg). second == l_s_rg [+RANGE_END]); }
return +EXIT_SUCCESS; }}
#endif
}

#ifdef SINGLE_TEST
int main (int p_argc, char const *const p_argv []) { return x:: test::
iterator_pair (+p_argc, p_argv); }
#endif

0 new messages