Re: std::string and case insensitive comparison
FWIW Here is a clener solution:
regards
Andy little
#include <locale>
#include <string>
#include <iterator>
#include <utility>
#include <algorithm>
#include <vector>
// random access containers only
// and only fwd iterator
template <typename Container>
struct pair_const_iterator{
typedef Container container_type;
pair_const_iterator(
container_type const & lhs_in,
container_type const & rhs_in,
typename container_type::size_type pos_in
):lhs(lhs_in),rhs(rhs_in),pos(pos_in){}
typedef std::pair<
typename Container::value_type,
typename Container::value_type
> value_type;
typedef value_type * pointer;
typedef value_type & reference;
typedef std::forward_iterator_tag iterator_category;
bool operator==(pair_const_iterator const & rhs)const
{
return pos == rhs.pos;
}
bool operator!=(pair_const_iterator const & rhs)const
{
return pos != rhs.pos;
}
value_type operator *() const
{
return value_type(lhs[pos],rhs[pos]);
}
pair_const_iterator const & operator++()
{
++pos;
return *this;
}
pair_const_iterator operator++(int)
{
pair_const_iterator temp = *this;
++pos;
return temp;
}
private:
typename container_type::size_type pos;
container_type const & lhs;
container_type const & rhs;
};
// sequence consisting of a pair of
// readonly containers
template <typename Container>
struct const_container_pair{
typedef Container container_type;
typedef std::pair<
typename Container::value_type,
typename Container::value_type
> value_type;
typedef pair_const_iterator<Container> const_iterator;
const_container_pair(
container_type const & lhs_in, container_type const & rhs_in
): lhs(lhs_in),rhs(rhs_in),
end_pos(std::min(lhs_in.size(),rhs_in.size())){}
const_container_pair(
container_type const & lhs_in, container_type const & rhs_in,
typename container_type::size_type end_pos_in
): lhs(lhs_in),rhs(rhs_in), end_pos(end_pos_in){}
const_iterator begin() const
{
return const_iterator(lhs,rhs,0);
}
const_iterator end() const
{
return const_iterator(lhs,rhs,end_pos);
}
private:
container_type const &lhs;
container_type const & rhs;
typename container_type::size_type const end_pos;
};
template <typename F>
struct not_equal_result{
not_equal_result(F const & f_in = F() )
:f(f_in){}
template <typename Pair>
bool operator()(Pair const & in)const
{
return f(in.first)!=f(in.second);
}
template<typename T1, typename T2>
bool operator()(T1 first, T2 second)const
{
return f(first)!=f(second);
}
private:
F f;
};
struct identity{
template <typename T>
T const & operator()(T const & in)const
{
return in;
}
};
//courtesy Kai-Uwe Box..
class to_lower {
std::locale const & loc;
public:
to_lower ( std::locale const & r_loc = std::locale() )
: loc ( r_loc )
{}
template < typename CharT >
CharT operator() ( CharT chr ) const {
return( std::tolower( chr, this->loc ) );
}
}; // class to_lower;
#include <iostream>
int main()
{
std::string str1 = "hi";
std::string str2 = "HI";
const_container_pair<std::string> pair(str1,str2);
bool res = std::find_if(
pair.begin(), pair.end(),not_equal_result<to_lower>()
) == pair.end();
std::cout << res <<'\n';
str1 += "de";
str2 += "LL";
//n.b pair expcts immutable containers
// create another pair to reflect size change...
const_container_pair<std::string> paira(str1,str2);
bool resa = std::find_if(
paira.begin(), paira.end(),not_equal_result<to_lower>()
) == paira.end();
std::cout << resa <<'\n';
std::vector<int> v1;
v1.push_back(1);
v1.push_back(2);
v1.push_back(3);
std::vector<int> v2;
v2.push_back(1);
v2.push_back(2);
v2.push_back(3);
const_container_pair<std::vector<int> > pair1(v1,v2);
bool res1 = std::find_if(
pair1.begin(), pair1.end(),not_equal_result<identity>()
) == pair1.end();
std::cout << res1 <<'\n';
v1.push_back(-1);
v2.push_back(2);
//as above
const_container_pair<std::vector<int> > pair2(v1,v2);
bool res2 = std::find_if(
pair2.begin(), pair2.end(),not_equal_result<identity>()
) == pair2.end();
std::cout << res2 <<'\n';
}