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
AMDG On 07/20/2012 10:52 AM, Brian Budge wrote:
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?
No there isn't. This requires compiler support. In Christ, Steven Watanabe
On Fri, Jul 20, 2012 at 1:00 PM, Steven Watanabe
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?
No there isn't. This requires compiler support.
I had feared as much. Is this case "fixed" in c++11? Thanks, Brian
On Fri, Jul 20, 2012 at 10:52 AM, Brian Budge
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
#include <iostream> template <typename T> struct is_memcpyable { static const bool value = boost::has_trivial_assign<T>::value; };
namespace boost { template<> struct has_trivial_assignEigen::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_memcpyableEigen::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_assignEigen::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
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
Okay, thanks for the suggestion Jeff. I'll look into it. Brian
participants (3)
-
Brian Budge
-
Jeffrey Lee Hellrung, Jr.
-
Steven Watanabe