// Copyright Joakim Karlsson & Kim Gräsman 2010-2012. // Distributed under the Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt or copy at // http://www.boost.org/LICENSE_1_0.txt) #ifndef IGLOO_CONSTRAINT_H #define IGLOO_CONSTRAINT_H namespace snowhouse { struct ConstraintOperator; typedef std::stack<bool> ResultStack; typedef std::stack<ConstraintOperator*> OperatorStack; template <typename HT, typename TT> struct ConstraintList { typedef HT HeadType; typedef TT TailType; ConstraintList(const HeadType& head, const TailType& tail) : m_head(head), m_tail(tail) { } HeadType m_head; TailType m_tail; }; struct Nil { Nil() {} Nil(const Nil&) {} }; // ---- These structs defines the resulting types of list concatenation operations template <typename L1, typename L2> struct type_concat { typedef ConstraintList<typename L1::HeadType, typename type_concat<typename L1::TailType, L2>::t> t; }; template <typename L2> struct type_concat<Nil, L2> { typedef L2 t; }; template <typename L3> inline L3 tr_concat(const Nil&, const Nil&) { return Nil(); } // ---- These structs define the concatenation operations. template <typename LeftList, typename RightList, typename ResultList> struct ListConcat { static ResultList Concatenate(const LeftList& left, const RightList& right) { return ResultList(left.m_head, ListConcat<typename LeftList::TailType, RightList, typename type_concat< typename LeftList::TailType, RightList>::t>::Concatenate(left.m_tail, right)); } }; // Concatenating an empty list with a second list yields the second list template <typename RightList, typename ResultList> struct ListConcat<Nil, RightList, ResultList> { static ResultList Concatenate(const Nil&, const RightList& right) { return right; } }; // Concatenating two empty lists yields an empty list template <typename ResultList> struct ListConcat<Nil, Nil, ResultList> { static ResultList Concatenate(const Nil&, const Nil&) { return Nil(); } }; // ---- The concatenation operation template <typename L1, typename L2> inline typename type_concat<L1, L2>::t Concatenate(const L1& list1, const L2& list2) { return ListConcat<L1, L2, typename type_concat<L1, L2>::t>::Concatenate(list1, list2); } } #endif