Goose  Artifact [6731c8b28b]

Artifact 6731c8b28b39f55cf3f3ff50dc6f9d2236a21a3e3d93d4329c4b326d43059fc8:

  • File bs/ir/decompose.h — part of check-in [8836bb4c35] at 2018-11-25 22:59:04 on branch trunk — ir: fixed a typo. (user: achavasse size: 2005)

#ifndef EMPATHY_IR_DECOMPOSE_H
#define EMPATHY_IR_DECOMPOSE_H

namespace empathy::ir
{
    template< typename T >
    struct LiteralSpec
    {
        using type = T;

        template< typename TT >
        LiteralSpec( TT&& val ) : m_val( forward< TT >( val ) )
        {}

        T m_val;
    };

    template< typename T >
    auto Lit( T&& val );

    template< typename T >
    struct Val
    {
        using type = T;
    };

    template< typename T >
    struct IsLiteralSpec : public false_type
    {};

    template< typename T >
    struct IsLiteralSpec< LiteralSpec< T > > : public true_type
    {};

    template< typename... T >
    struct VecDecompositionReturnTypeBuilder
    {};

    template< typename... TU >
    struct VecDecompositionReturnTypeBuilder< tuple< TU... > >
    {
        using type = tuple< TU... >;
    };

    template< typename... TU, typename HS, typename... TS >
    struct VecDecompositionReturnTypeBuilder< tuple< TU... >, HS, TS... >
    {
        using type = conditional_t< IsLiteralSpec< HS >::value,
            typename VecDecompositionReturnTypeBuilder< tuple< TU... >, TS... >::type,
            typename VecDecompositionReturnTypeBuilder< tuple< TU..., typename HS::type >, TS... >::type
        >;
    };

    template< typename... S >
    struct VectorSpec
    {
        using type = typename VecDecompositionReturnTypeBuilder< tuple<>, S... >::type;

        template< typename... T >
        VectorSpec( T&&... specs ) :
            m_specs( forward< T >( specs )... )
        {}

        tuple< S... > m_specs;
    };

    template< typename... S >
    auto Vec( S&&... specs );

    template< typename T >
    bool Decompose( const Term& t, const LiteralSpec< T >& spec );

    template< typename T >
    optional< reference_wrapper< const T > > Decompose( const Term& t, const Val< T >& spec );

    template< typename... S >
    optional< typename VectorSpec< S... >::type > Decompose( const Term& t, const VectorSpec< S... >& spec );
}

#endif