Boost logo

Boost :

Subject: Re: [boost] [type_traits] has_equal_to< std::vector<T> > always true_
From: Lorenzo Caminiti (lorcaminiti_at_[hidden])
Date: 2012-07-04 15:12:00


On Mon, Apr 30, 2012 at 9:08 PM, lcaminiti <lorcaminiti_at_[hidden]> wrote:
> Yes, plus I don't have much time now... I wanted to know that there's
> agreement in fixing this so if I spend time fixing it won't be lost. I'll
> see what I can do for 1.50, if not then we'll try for 1.51.

Maybe this will make it in 1.52... let's start discussing how the
specializations should be implemented. Let's start with std::vector as
an example.

Are these specializations enough or I've missed some test case (see main):

#include <boost/type_traits/has_equal_to.hpp>

// add these specializations to boost/type_traits/has_equal_to.hpp

namespace std { // fwd decl so no need to include STL

template< typename T, class Alloc > class vector;

} // namespace std

namespace boost {

template< typename T, class Alloc >
struct has_equal_to < std::vector<T, Alloc> >
    : has_equal_to<T>
{};

template< typename T, class LhsAlloc, class RhsAlloc, typename Ret >
struct has_equal_to
    <
          std::vector<T, LhsAlloc >
        , std::vector<T, RhsAlloc >
        , Ret
>
    : has_equal_to<T, T, Ret>
{};

} // namespace boost

// test program

#include <boost/detail/lightweight_test.hpp>
#include <vector>
#include <iostream>

struct xyz {}; // this type has no operator==

int main ( void )
{
    typedef std::vector<int> vi;
    typedef std::vector<xyz> vx;

    // vi i;
    // vx x;
    // i == i; // ok
    // x == x; // error
    // x == i; // error
    // i == x; // error

    // 1 tparam
    BOOST_TEST((boost::has_equal_to<vi>::value)); // ok: i == i
    BOOST_TEST((!boost::has_equal_to<vx>::value)); // error: x == x
    // 2 tparams
    BOOST_TEST((boost::has_equal_to<vi, vi>::value)); // ok: i == i
    BOOST_TEST((!boost::has_equal_to<vx, vx>::value)); // error: x == x
    BOOST_TEST((!boost::has_equal_to<vx, vi>::value)); // error: x == i
    BOOST_TEST((!boost::has_equal_to<vi, vx>::value)); // error: i == x
    // 3 tparams
    BOOST_TEST((boost::has_equal_to<vi, vi, char>::value)); // ok: i == i
    BOOST_TEST((!boost::has_equal_to<vx, vx, char>::value)); // error: x == x
    BOOST_TEST((!boost::has_equal_to<vx, vi, char>::value)); // error: x == i
    BOOST_TEST((!boost::has_equal_to<vi, vx, char>::value)); // error: i == x

    return boost::report_errors();
}

Also, if I forward declare the templates I need from STL, I don't need
to #include the STL. This way there is no draw back in declaring the
specializations directly in boost/type_traits/has_equal_to.hpp (or, is
there?) instead that in a separate header
boost/type_traits/std/vector.hpp. The advantage of this is that
boost::has_equal_to<vector<T> > will do what the user expects "out of
the box" and without requiring the user to know and remember to
include the extra header type_traits/std/vector.hpp.

Thanks.
--Lorenzo


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk