Boost logo

Boost Users :

Subject: [Boost-users] [type_traits] defining my own trait
From: Brian Budge (brian.budge_at_[hidden])
Date: 2012-07-20 13:52:11


Hi all -

I am hoping to define my own type trait is_memcpyable.

I'm trying to start off simple:

template <typename T>
struct is_memcpyable {
    static const bool value = boost::has_trivial_assign<T>::value;
};

Then when I encounter types in my code that are safe to memcpy, but
don't have a trivial assignment operator I can specialize the trait.

I'm having trouble with inheritance and composition. I'm hoping
someone can help. Here's a complete code sample:

/***START OF SAMPLE***/
#include <Eigen/Dense>
#include <iostream>

template <typename T>
struct is_memcpyable {
    static const bool value = boost::has_trivial_assign<T>::value;
};

namespace boost {
    template<>
    struct has_trivial_assign<Eigen::Vector3f> : public true_type {};
}

struct foo : public Eigen::Vector3f {

    foo() {}

};

struct bar {
    bar(int i) : m_vec(float(i), float(i), float(i)) {}

    Eigen::Vector3f m_vec;
};

int main(int argc, char **args) {

    std::cerr << "memcpyable int: " << is_memcpyable<int>::value << std::endl;
    std::cerr << "memcpyable v3f: " <<
is_memcpyable<Eigen::Vector3f>::value << std::endl;
    std::cerr << "memcpyable bar: " << is_memcpyable<bar>::value << std::endl;
    std::cerr << "memcpyable foo: " << is_memcpyable<foo>::value << std::endl;

    std::cerr << "trivial assign int: " <<
boost::has_trivial_assign<int>::value << std::endl;
    std::cerr << "trivial assign v3f: " <<
boost::has_trivial_assign<Eigen::Vector3f>::value << std::endl;
    std::cerr << "trivial assign bar: " <<
boost::has_trivial_assign<bar>::value << std::endl;
    std::cerr << "trivial assign foo: " <<
boost::has_trivial_assign<foo>::value << std::endl;

    return 0;
}
/***END OF SAMPLE***/

The Eigen library is set up to do nifty expression template goodness
all over the place, which means that they implement operator = for the
types in the library. However, once a value is assigned, the storage
is fixed (at least for the Dense matrix types). The data layout is
fixed, and internal storage is a small array of builtin types.

What I would like to happen is that all 8 print statements should be
true; however, the ones for bar and foo are false. I can explicitly
set their type traits, but this quickly gets out of hand.

I guess the real question is this: is there a way to define
is_memcpyable so that the value is true if a class does not define
operator=, and all of it's members or inherited types are also
memcpyable?

Thanks for any help.
  Brian


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net