#ifndef SASS_OPERATION_H
#define SASS_OPERATION_H
#include "ast_fwd_decl.hpp"
namespace Sass {
template<typename T>
class Operation {
public:
virtual T operator()(AST_Node_Ptr x) = 0;
virtual ~Operation() { }
// statements
virtual T operator()(Block_Ptr x) = 0;
virtual T operator()(Ruleset_Ptr x) = 0;
virtual T operator()(Bubble_Ptr x) = 0;
virtual T operator()(Trace_Ptr x) = 0;
virtual T operator()(Supports_Block_Ptr x) = 0;
virtual T operator()(Media_Block_Ptr x) = 0;
virtual T operator()(At_Root_Block_Ptr x) = 0;
virtual T operator()(Directive_Ptr x) = 0;
virtual T operator()(Keyframe_Rule_Ptr x) = 0;
virtual T operator()(Declaration_Ptr x) = 0;
virtual T operator()(Assignment_Ptr x) = 0;
virtual T operator()(Import_Ptr x) = 0;
virtual T operator()(Import_Stub_Ptr x) = 0;
virtual T operator()(Warning_Ptr x) = 0;
virtual T operator()(Error_Ptr x) = 0;
virtual T operator()(Debug_Ptr x) = 0;
virtual T operator()(Comment_Ptr x) = 0;
virtual T operator()(If_Ptr x) = 0;
virtual T operator()(For_Ptr x) = 0;
virtual T operator()(Each_Ptr x) = 0;
virtual T operator()(While_Ptr x) = 0;
virtual T operator()(Return_Ptr x) = 0;
virtual T operator()(Content_Ptr x) = 0;
virtual T operator()(Extension_Ptr x) = 0;
virtual T operator()(Definition_Ptr x) = 0;
virtual T operator()(Mixin_Call_Ptr x) = 0;
// expressions
virtual T operator()(List_Ptr x) = 0;
virtual T operator()(Map_Ptr x) = 0;
virtual T operator()(Binary_Expression_Ptr x) = 0;
virtual T operator()(Unary_Expression_Ptr x) = 0;
virtual T operator()(Function_Call_Ptr x) = 0;
virtual T operator()(Function_Call_Schema_Ptr x) = 0;
virtual T operator()(Custom_Warning_Ptr x) = 0;
virtual T operator()(Custom_Error_Ptr x) = 0;
virtual T operator()(Variable_Ptr x) = 0;
virtual T operator()(Number_Ptr x) = 0;
virtual T operator()(Color_Ptr x) = 0;
virtual T operator()(Boolean_Ptr x) = 0;
virtual T operator()(String_Schema_Ptr x) = 0;
virtual T operator()(String_Quoted_Ptr x) = 0;
virtual T operator()(String_Constant_Ptr x) = 0;
virtual T operator()(Supports_Condition_Ptr x) = 0;
virtual T operator()(Supports_Operator_Ptr x) = 0;
virtual T operator()(Supports_Negation_Ptr x) = 0;
virtual T operator()(Supports_Declaration_Ptr x) = 0;
virtual T operator()(Supports_Interpolation_Ptr x) = 0;
virtual T operator()(Media_Query_Ptr x) = 0;
virtual T operator()(Media_Query_Expression_Ptr x) = 0;
virtual T operator()(At_Root_Query_Ptr x) = 0;
virtual T operator()(Null_Ptr x) = 0;
virtual T operator()(Parent_Selector_Ptr x) = 0;
// parameters and arguments
virtual T operator()(Parameter_Ptr x) = 0;
virtual T operator()(Parameters_Ptr x) = 0;
virtual T operator()(Argument_Ptr x) = 0;
virtual T operator()(Arguments_Ptr x) = 0;
// selectors
virtual T operator()(Selector_Schema_Ptr x) = 0;
virtual T operator()(Placeholder_Selector_Ptr x) = 0;
virtual T operator()(Element_Selector_Ptr x) = 0;
virtual T operator()(Class_Selector_Ptr x) = 0;
virtual T operator()(Id_Selector_Ptr x) = 0;
virtual T operator()(Attribute_Selector_Ptr x) = 0;
virtual T operator()(Pseudo_Selector_Ptr x) = 0;
virtual T operator()(Wrapped_Selector_Ptr x) = 0;
virtual T operator()(Compound_Selector_Ptr x)= 0;
virtual T operator()(Complex_Selector_Ptr x) = 0;
virtual T operator()(Selector_List_Ptr x) = 0;
template <typename U>
T fallback(U x) { return T(); }
};
template <typename T, typename D>
class Operation_CRTP : public Operation<T> {
public:
D& impl() { return static_cast<D&>(*this); }
public:
T operator()(AST_Node_Ptr x) { return static_cast<D*>(this)->fallback(x); }
// statements
T operator()(Block_Ptr x) { return static_cast<D*>(this)->fallback(x); }
T operator()(Ruleset_Ptr x) { return static_cast<D*>(this)->fallback(x); }
T operator()(Bubble_Ptr x) { return static_cast<D*>(this)->fallback(x); }
T operator()(Trace_Ptr x) { return static_cast<D*>(this)->fallback(x); }
T operator()(Supports_Block_Ptr x) { return static_cast<D*>(this)->fallback(x); }
T operator()(Media_Block_Ptr x) { return static_cast<D*>(this)->fallback(x); }
T operator()(At_Root_Block_Ptr x) { return static_cast<D*>(this)->fallback(x); }
T operator()(Directive_Ptr x) { return static_cast<D*>(this)->fallback(x); }
T operator()(Keyframe_Rule_Ptr x) { return static_cast<D*>(this)->fallback(x); }
T operator()(Declaration_Ptr x) { return static_cast<D*>(this)->fallback(x); }
T operator()(Assignment_Ptr x) { return static_cast<D*>(this)->fallback(x); }
T operator()(Import_Ptr x) { return static_cast<D*>(this)->fallback(x); }
T operator()(Import_Stub_Ptr x) { return static_cast<D*>(this)->fallback(x); }
T operator()(Warning_Ptr x) { return static_cast<D*>(this)->fallback(x); }
T operator()(Error_Ptr x) { return static_cast<D*>(this)->fallback(x); }
T operator()(Debug_Ptr x) { return static_cast<D*>(this)->fallback(x); }
T operator()(Comment_Ptr x) { return static_cast<D*>(this)->fallback(x); }
T operator()(If_Ptr x) { return static_cast<D*>(this)->fallback(x); }
T operator()(For_Ptr x) { return static_cast<D*>(this)->fallback(x); }
T operator()(Each_Ptr x) { return static_cast<D*>(this)->fallback(x); }
T operator()(While_Ptr x) { return static_cast<D*>(this)->fallback(x); }
T operator()(Return_Ptr x) { return static_cast<D*>(this)->fallback(x); }
T operator()(Content_Ptr x) { return static_cast<D*>(this)->fallback(x); }
T operator()(Extension_Ptr x) { return static_cast<D*>(this)->fallback(x); }
T operator()(Definition_Ptr x) { return static_cast<D*>(this)->fallback(x); }
T operator()(Mixin_Call_Ptr x) { return static_cast<D*>(this)->fallback(x); }
// expressions
T operator()(List_Ptr x) { return static_cast<D*>(this)->fallback(x); }
T operator()(Map_Ptr x) { return static_cast<D*>(this)->fallback(x); }
T operator()(Binary_Expression_Ptr x) { return static_cast<D*>(this)->fallback(x); }
T operator()(Unary_Expression_Ptr x) { return static_cast<D*>(this)->fallback(x); }
T operator()(Function_Call_Ptr x) { return static_cast<D*>(this)->fallback(x); }
T operator()(Function_Call_Schema_Ptr x) { return static_cast<D*>(this)->fallback(x); }
T operator()(Custom_Warning_Ptr x) { return static_cast<D*>(this)->fallback(x); }
T operator()(Custom_Error_Ptr x) { return static_cast<D*>(this)->fallback(x); }
T operator()(Variable_Ptr x) { return static_cast<D*>(this)->fallback(x); }
T operator()(Number_Ptr x) { return static_cast<D*>(this)->fallback(x); }
T operator()(Color_Ptr x) { return static_cast<D*>(this)->fallback(x); }
T operator()(Boolean_Ptr x) { return static_cast<D*>(this)->fallback(x); }
T operator()(String_Schema_Ptr x) { return static_cast<D*>(this)->fallback(x); }
T operator()(String_Constant_Ptr x) { return static_cast<D*>(this)->fallback(x); }
T operator()(String_Quoted_Ptr x) { return static_cast<D*>(this)->fallback(x); }
T operator()(Supports_Condition_Ptr x) { return static_cast<D*>(this)->fallback(x); }
T operator()(Supports_Operator_Ptr x) { return static_cast<D*>(this)->fallback(x); }
T operator()(Supports_Negation_Ptr x) { return static_cast<D*>(this)->fallback(x); }
T operator()(Supports_Declaration_Ptr x) { return static_cast<D*>(this)->fallback(x); }
T operator()(Supports_Interpolation_Ptr x) { return static_cast<D*>(this)->fallback(x); }
T operator()(Media_Query_Ptr x) { return static_cast<D*>(this)->fallback(x); }
T operator()(Media_Query_Expression_Ptr x) { return static_cast<D*>(this)->fallback(x); }
T operator()(At_Root_Query_Ptr x) { return static_cast<D*>(this)->fallback(x); }
T operator()(Null_Ptr x) { return static_cast<D*>(this)->fallback(x); }
T operator()(Parent_Selector_Ptr x) { return static_cast<D*>(this)->fallback(x); }
// parameters and arguments
T operator()(Parameter_Ptr x) { return static_cast<D*>(this)->fallback(x); }
T operator()(Parameters_Ptr x) { return static_cast<D*>(this)->fallback(x); }
T operator()(Argument_Ptr x) { return static_cast<D*>(this)->fallback(x); }
T operator()(Arguments_Ptr x) { return static_cast<D*>(this)->fallback(x); }
// selectors
T operator()(Selector_Schema_Ptr x) { return static_cast<D*>(this)->fallback(x); }
T operator()(Placeholder_Selector_Ptr x) { return static_cast<D*>(this)->fallback(x); }
T operator()(Element_Selector_Ptr x) { return static_cast<D*>(this)->fallback(x); }
T operator()(Class_Selector_Ptr x) { return static_cast<D*>(this)->fallback(x); }
T operator()(Id_Selector_Ptr x) { return static_cast<D*>(this)->fallback(x); }
T operator()(Attribute_Selector_Ptr x) { return static_cast<D*>(this)->fallback(x); }
T operator()(Pseudo_Selector_Ptr x) { return static_cast<D*>(this)->fallback(x); }
T operator()(Wrapped_Selector_Ptr x) { return static_cast<D*>(this)->fallback(x); }
T operator()(Compound_Selector_Ptr x){ return static_cast<D*>(this)->fallback(x); }
T operator()(Complex_Selector_Ptr x) { return static_cast<D*>(this)->fallback(x); }
T operator()(Selector_List_Ptr x) { return static_cast<D*>(this)->fallback(x); }
template <typename U>
T fallback(U x) { return T(); }
};
}
#endif