#ifndef GOOSE_BUILTINS_TYPES_TUPLE_H
#define GOOSE_BUILTINS_TYPES_TUPLE_H
namespace goose::builtins
{
extern void SetupTupleUnification( Env& e );
extern Value MkTupleType( const Term& state, const Term& types );
extern Value TupleOfTypesToTupleType( const Value& tup );
extern const Value& EmptyTupleType();
extern const Value& EmptyClosedTupleType();
extern const Value& EmptyTuple();
extern const Value& EmptyClosedTuple();
extern Value AppendToTupleType( const Value& tuptype, const Value& type );
extern Value AppendToTuple( const Value& tup, const Value& val );
extern Value PrependToTupleType( const Value& type, const Value& tuptype );
extern Value PrependToTuple( const Value& val, const Value& tup );
extern Value ConcatenateTupleTypes( const Value& ltup, const Value& rtup );
extern Value ConcatenateTuples( const Value& ltup, const Value& rtup );
template< typename... V >
Value MakeTuple( V&&... values );
extern bool IsTuple( const Value& t );
extern bool IsOpenTuple( const Value& t );
extern Value CloseTuple( const Value& tup );
extern size_t TupleSize( const Value& tup );
template< typename F >
void ForEachInTuple( const Value& tup, F&& func );
template< typename F >
bool ForEachInTuples( const Value& tup1, const Value& tup2, F&& func );
// Returns true if the tuple and all values it contains (including nested tuples)
// are all constant.
extern bool IsTupleConstant( const Value& tup );
// Helper to provide generic param patterns for tuples
struct TuplePattern
{
static const Term& GetPattern();
static optional< Term > GetDomain() { return sema::DomainCompileTime(); }
};
}
namespace goose::ir
{
template< typename... T >
struct Bridge< tuple< T... > >
{
static optional< Term > Domain() { return sema::DomainCompileTime(); }
static const Term& Type();
static Value ToValue( const tuple< T... >& x );
static optional< tuple< T... > > FromVectorTerm( const Term& v );
static optional< tuple< T... > > FromValue( const Value& v );
};
}
#endif