Use type-traits structs for vector configuration

Issue #339 resolved
Jordan Moxon created an issue

Hi Klaus,

I’d like to suggest a collection of type aliases currently in blaze/math/Aliases.h be wrapped in type-trait structs to assist with user-defined customization. The principal example is TransposeType_t. Currently, it is defined as:

template <typename T>
using TransposeType_t = typename T::TransposeType;

And it would be more helpful if it were defined as:

namespace type_traits {
template <typename T>
struct TransposeType {
  using type = typename T::TransposeType;
};
}

template <typename T>
using TransposeType_t = typename type_traits::TransposeType<T>::type;

Our reasoning for this suggestion is a desired use-case of CustomVector – in particular, we would like to create a user-defined vector class that inherits from CustomVector, taking advantage of the Blaze expression templates, but also has a ResultType of the user-defined class itself. The inheritance would have the CRTP pattern:

class UserDefinedVector 
  : public blaze::CustomVector<double, blaze::unaligned, blaze::unpadded,
                               blaze::defaultTransposeFlag, UserDefinedVector> {
/*user-defined behavior*/
};

However, because the TransposeType of CustomVector will in the current configuration try to access UserDefinedVector::TransposeType, which will not exist in the CRTP evaluation (because UserDefinedVector will incomplete at that point), this inheritance will fail.

The additional type-traits struct suggested above would allow us to create an explicit template specialization of type_traits::TransposeType for UserDefinedVector, and permit the CRTP use of CustomVector.

Cheers,

Jordan

Comments (8)

  1. Klaus Iglberger

    Hi Jordan!

    Thanks a lot for creating this proposal. I completely understand the rational and see the advantage of this additional compile time indirection. I’ll see what I can do.

    I’m curious to learn, though, what the “user-defined behavior” represents. Could you please give me some insight into what additional behavior UserDefinedVector comes with? I’m curious because all operations working with the CRTP base class DenseVector are only able to “see” a CustomVector. Are the type alias wrappers generally enough? Is the request somehow related to issue #166?

    Best regards,

    Klaus!

  2. Jordan Moxon reporter

    Hi Klaus,

    Sorry for the delay - Indeed, you’ve identified precisely the earlier part of this story in issue #166 . Ultimately, we’d like to get to a stage where we can entirely remove our PointerVector adapter that Nils mentioned in that issue in favor of inheriting from CustomVector directly. To summarize part of the discussion from that previous thread, the hope is to constrain the set of allowed math operations associated with the derived classes depending on the type of data they are intended to hold, and similarly propagate those constraints through intricate expressions. The adapter we currently use manages this, and the derived classes impose the constraints through template specializations of MapTrait, along with static_asserts to disallow operations that don’t make physical sense.

    I can do a bit of experimentation to determine whether the type alias indirection would be sufficient to entirely satisfy our target use-case.

    Thanks,

    Jordan

  3. Jordan Moxon reporter

    Hi Klaus,

    After a few more tests, I believe that the additional indirection provided by the type-traits structs under discussion will be sufficient for our use case, and would allow us to eliminate a great deal of adapter code that duplicates functionality already in Blaze.

    Thanks again for all of your assistance!

    Cheers,

    Jordan

  4. Klaus Iglberger

    Hi Jordan!

    With the next push you’ll get the CustomTransposeType and CustomOppositeType type traits, which will enable you to provide custom types for the TransposeType and OppositeType of a CustomVector and CustomMatrix. Additionally, you’ll get a solution for issue #166: You’ll be able to tag all vector and matrix types in order to define distinct groups. There will be predefined groups that enable all operations, but it will also be possible to define custom groups and restrict operations (as for instance required to model physical quantities). I hope that the solutions for #166 and #339 together will enable you to do exactly what you have in mind.

    Best regards,

    Klaus!

  5. Log in to comment