#ifndef EMPATHY_BUILTINS_TYPES_TEMPLATE_TFUNC_H
#define EMPATHY_BUILTINS_TYPES_TEMPLATE_TFUNC_H

namespace empathy::builtins
{
    extern void SetupTemplateFunctionInvocationRule( Env& e );
    extern void SetupTemplateFunctionUnification( Env& e );

    class TFunc
    {
        public:
            template< typename T, typename S, typename I, typename V >
            TFunc( T&& type, S&& signature, I&& identity, V&& toks ) :
                m_type( forward< T >( type ) ),
                m_signature( forward< S >( signature ) ),
                m_identity( forward< I >( identity ) ),
                m_toks( forward< V >( toks ) )
            {}

            const auto& type() const { return m_type; }
            const auto& signature() const { return m_signature; }
            const auto& identity() const { return m_identity; }
            const auto& toks() const { return m_toks; }

        private:
            TFuncType                   m_type;
            Term                        m_signature;
            Term                        m_identity;
            ptr< vector< ir::Term > >   m_toks;
    };

    extern optional< Value > InstantiateTFunc( const Context& c, const Value& callee, const Term& unifiedCallPat, UnificationContext& uc );
}

namespace empathy::ir
{
    template<>
    struct Bridge< builtins::TFunc >
    {
        static Term Type( const builtins::TFunc& tf );
        static Value ToValue( const builtins::TFunc& tf );
        static optional< builtins::TFunc > FromValue( const Value& v );
    };
}

#endif
