//
// Cforall Version 1.0.0 Copyright (C) 2015 University of Waterloo
//
// The contents of this file are covered under the licence agreement in the
// file "LICENCE" distributed with Cforall.
//
// ForallSubstitutor.hpp --
//
// Author           : Aaron B. Moss
// Created On       : Wed Jun 26 15:00:00 2019
// Last Modified By : Aaron B. Moss
// Last Modified On : Wed Jun 26 15:00:00 2019
// Update Count     : 1
//

#include "Pass.hpp"

namespace ast {

class Expr;

/// Visitor that correctly substitutes TypeDecl while maintaining TypeInstType bindings.
/// Also has some convenience methods to mutate fields.
struct ForallSubstitutor : public WithForallSubstitutor, public WithVisitorRef<ForallSubstitutor> {
	/// Substitute TypeInstType base type
	readonly< TypeDecl > operator() ( const readonly< TypeDecl > & o ) {
		return subs.replace( o );
	}
	
	/// Make new forall-list clone
	ParameterizedType::ForallList operator() ( const ParameterizedType::ForallList & o ) {
		return subs.clone( o, *visitor );
	}

	template<typename node_t > 
	std::vector<ptr<node_t>> operator() (const std::vector<ptr<node_t>> & o) {
		std::vector<ptr<node_t>> n;
		n.reserve(o.size());
		for (const node_t * d : o) { n.emplace_back(d->accept(*visitor)); }
		return n;
	}
	
	/*

	/// Substitute parameter/return type
	std::vector< ptr< DeclWithType > > operator() ( const std::vector< ptr< DeclWithType > > & o ) {
		std::vector< ptr< DeclWithType > > n;
		n.reserve( o.size() );
		for ( const DeclWithType * d : o ) { n.emplace_back( d->accept( *visitor ) ); }
		return n;
	}

	/// Substitute type parameter list
	std::vector< ptr< Expr > > operator() ( const std::vector< ptr< Expr > > & o ) {
		std::vector< ptr< Expr > > n;
		n.reserve( o.size() );
		for ( const Expr * d : o ) { n.emplace_back( d->accept( *visitor ) ); }
		return n;
	}

	*/
};

} // namespace ast

// Local Variables: //
// tab-width: 4 //
// mode: c++ //
// compile-command: "make install" //
// End: //
