Boost logo

Boost Users :

Subject: Re: [Boost-users] [type_traits] defining my own trait
From: Jeffrey Lee Hellrung, Jr. (jeffrey.hellrung_at_[hidden])
Date: 2012-07-20 20:05:06


On Fri, Jul 20, 2012 at 10:52 AM, Brian Budge <brian.budge_at_[hidden]> wrote:

> 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?
>

As Steven said, no, but one thing that may minimize the boilerplate is for
the default implementation to detect whether a specific typedef is present
(e.g., is_memcpyable_tag), and, if so, use T::is_memcpyable_tag::value for
the value of is_memcpyable<T>::value. Then write a macro that typedef's
is_memcpyable_tag given a set of base and member objects, which makes your
class definitions something like

struct foo : public Eigen::Vector3f
{
    TYPEDEF_IS_MEMCPYABLE_TAG( ( Eigen::Vector3f ) )
};

struct bar
{
    TYPEDEF_IS_MEMCPYABLE_TAG( ( Eigen::Vector3f ) ( X ) )

    Eigen::Vector3f m_vec;
    X some_member;
};

This is something maybe to consider, anyway.

- Jeff



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