spec_tree.hh

00001 /* vim: set sw=4 sts=4 et foldmethod=syntax : */
00002 
00003 /*
00004  * Copyright (c) 2008, 2009 Ciaran McCreesh
00005  *
00006  * This file is part of the Paludis package manager. Paludis is free software;
00007  * you can redistribute it and/or modify it under the terms of the GNU General
00008  * Public License version 2, as published by the Free Software Foundation.
00009  *
00010  * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
00011  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00012  * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
00013  * details.
00014  *
00015  * You should have received a copy of the GNU General Public License along with
00016  * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
00017  * Place, Suite 330, Boston, MA  02111-1307  USA
00018  */
00019 
00020 #ifndef PALUDIS_GUARD_PALUDIS_SPEC_TREE_HH
00021 #define PALUDIS_GUARD_PALUDIS_SPEC_TREE_HH 1
00022 
00023 #include <paludis/spec_tree-fwd.hh>
00024 #include <paludis/util/wrapped_forward_iterator-fwd.hh>
00025 #include <paludis/util/select.hh>
00026 #include <paludis/util/simple_visitor.hh>
00027 #include <paludis/util/sequence-fwd.hh>
00028 
00029 #include <paludis/util/sequence-impl.hh>
00030 #include <paludis/util/accept_visitor.hh>
00031 #include <paludis/util/indirect_iterator-impl.hh>
00032 #include <paludis/util/make_shared_ptr.hh>
00033 #include <algorithm>
00034 
00035 namespace paludis
00036 {
00037     namespace spec_tree_internals
00038     {
00039         template <typename Tree_>
00040         class PALUDIS_VISIBLE BasicNode :
00041             public virtual DeclareAbstractAcceptMethods<BasicNode<Tree_>, typename Tree_::VisitableTypeList>
00042         {
00043         };
00044 
00045         template <typename Tree_, typename Item_>
00046         class PALUDIS_VISIBLE LeafNode :
00047             public BasicNode<Tree_>,
00048             public ImplementAcceptMethods<BasicNode<Tree_>, LeafNode<Tree_, Item_> >
00049         {
00050             private:
00051                 const std::tr1::shared_ptr<const Item_> _spec;
00052 
00053             public:
00054                 explicit LeafNode(const std::tr1::shared_ptr<const Item_> & i);
00055 
00056                 template <typename OtherTree_>
00057                 operator LeafNode<OtherTree_, Item_> () const;
00058 
00059                 const std::tr1::shared_ptr<const Item_> spec() const;
00060         };
00061 
00062         template <typename Tree_, typename Item_>
00063         struct InnerNode;
00064 
00065         template <typename Tree_>
00066         class PALUDIS_VISIBLE BasicInnerNode :
00067             public BasicNode<Tree_>
00068         {
00069             private:
00070                 typedef Sequence<std::tr1::shared_ptr<const BasicNode<Tree_> > > ChildList;
00071                 std::tr1::shared_ptr<ChildList> _child_list;
00072 
00073             public:
00074                 BasicInnerNode();
00075 
00076                 struct ConstIteratorTag;
00077                 typedef WrappedForwardIterator<ConstIteratorTag,
00078                         const std::tr1::shared_ptr<const BasicNode<Tree_> > > ConstIterator;
00079 
00080                 ConstIterator begin() const;
00081 
00082                 ConstIterator end() const;
00083 
00084                 void append_node(const std::tr1::shared_ptr<const BasicNode<Tree_> > & t);
00085 
00086                 template <typename T_>
00087                 const std::tr1::shared_ptr<typename Tree_::template NodeType<T_>::Type>
00088                 append(const std::tr1::shared_ptr<const T_> & t);
00089 
00090                 template <typename T_>
00091                 const std::tr1::shared_ptr<typename Tree_::template NodeType<T_>::Type>
00092                 append(const std::tr1::shared_ptr<T_> & t);
00093         };
00094 
00095         template <typename Tree_, typename Item_>
00096         class PALUDIS_VISIBLE InnerNode :
00097             public BasicInnerNode<Tree_>,
00098             public ImplementAcceptMethods<BasicNode<Tree_>, InnerNode<Tree_, Item_> >
00099         {
00100             private:
00101                 const std::tr1::shared_ptr<const Item_> _spec;
00102 
00103             public:
00104                 explicit InnerNode(const std::tr1::shared_ptr<const Item_> & i);
00105 
00106                 template <typename OtherTree_>
00107                 operator InnerNode<OtherTree_, Item_> () const;
00108 
00109                 const std::tr1::shared_ptr<const Item_> spec() const;
00110         };
00111 
00112         template <typename Tree_>
00113         struct MakeVisitableTypeListEntry<Tree_, TypeListTail>
00114         {
00115             typedef TypeListTail Type;
00116         };
00117 
00118         template <typename Tree_, typename Item_, typename Tail_>
00119         struct MakeVisitableTypeListEntry<Tree_, TypeListEntry<SpecTreeInnerNodeType<Item_>, Tail_> >
00120         {
00121             typedef TypeListEntry<InnerNode<Tree_, Item_>,
00122                     typename MakeVisitableTypeListEntry<Tree_, Tail_>::Type> Type;
00123         };
00124 
00125         template <typename Tree_, typename Item_, typename Tail_>
00126         struct MakeVisitableTypeListEntry<Tree_, TypeListEntry<SpecTreeLeafNodeType<Item_>, Tail_> >
00127         {
00128             typedef TypeListEntry<LeafNode<Tree_, Item_>,
00129                     typename MakeVisitableTypeListEntry<Tree_, Tail_>::Type> Type;
00130         };
00131 
00132         template <typename Tree_, typename NodeList_>
00133         struct MakeVisitableTypeList
00134         {
00135             typedef typename MakeVisitableTypeListEntry<Tree_, NodeList_>::Type Type;
00136         };
00137     }
00138 
00139     template <typename NodeList_, typename RootNode_>
00140     class PALUDIS_VISIBLE SpecTree
00141     {
00142         public:
00143             typedef typename spec_tree_internals::MakeVisitableTypeList<SpecTree, NodeList_>::Type VisitableTypeList;
00144 
00145             typedef spec_tree_internals::BasicNode<SpecTree> BasicNode;
00146             typedef spec_tree_internals::BasicInnerNode<SpecTree> BasicInnerNode;
00147 
00148             template <typename Node_>
00149             struct LeafNodeType
00150             {
00151                 typedef spec_tree_internals::LeafNode<SpecTree, Node_> Type;
00152             };
00153 
00154             template <typename Node_>
00155             struct InnerNodeType
00156             {
00157                 typedef spec_tree_internals::InnerNode<SpecTree, Node_> Type;
00158             };
00159 
00160             template <typename Node_>
00161             struct NodeType
00162             {
00163                 typedef typename Select<
00164                     TypeListContains<VisitableTypeList, typename LeafNodeType<Node_>::Type>::value,
00165                     typename SpecTree::template LeafNodeType<Node_>::Type,
00166                     typename Select<
00167                         TypeListContains<VisitableTypeList, typename InnerNodeType<Node_>::Type>::value,
00168                         typename InnerNodeType<Node_>::Type,
00169                         spec_tree_internals::TreeCannotContainNodeType<SpecTree, Node_>
00170                             >::Type
00171                     >::Type Type;
00172             };
00173 
00174             explicit SpecTree(const std::tr1::shared_ptr<RootNode_> & spec);
00175 
00176             explicit SpecTree(const std::tr1::shared_ptr<const RootNode_> & spec);
00177 
00178             const std::tr1::shared_ptr<typename InnerNodeType<RootNode_>::Type> root();
00179 
00180             const std::tr1::shared_ptr<const typename InnerNodeType<RootNode_>::Type> root() const;
00181 
00182             typedef Formatter<
00183                 typename Select<TypeListContains<VisitableTypeList, typename NodeType<PackageDepSpec>::Type>::value,
00184                          PackageDepSpec, NoType<1u> >::Type,
00185                 typename Select<TypeListContains<VisitableTypeList, typename NodeType<BlockDepSpec>::Type>::value,
00186                          BlockDepSpec, NoType<2u> >::Type,
00187                 typename Select<TypeListContains<VisitableTypeList, typename NodeType<FetchableURIDepSpec>::Type>::value,
00188                          FetchableURIDepSpec, NoType<3u> >::Type,
00189                 typename Select<TypeListContains<VisitableTypeList, typename NodeType<SimpleURIDepSpec>::Type>::value,
00190                          SimpleURIDepSpec, NoType<4u> >::Type,
00191                 typename Select<TypeListContains<VisitableTypeList, typename NodeType<DependencyLabelsDepSpec>::Type>::value,
00192                          DependencyLabelsDepSpec, NoType<5u> >::Type,
00193                 typename Select<TypeListContains<VisitableTypeList, typename NodeType<URILabelsDepSpec>::Type>::value,
00194                          URILabelsDepSpec, NoType<6u> >::Type,
00195                 typename Select<TypeListContains<VisitableTypeList, typename NodeType<PlainTextDepSpec>::Type>::value,
00196                          PlainTextDepSpec, NoType<7u> >::Type,
00197                 typename Select<TypeListContains<VisitableTypeList, typename NodeType<LicenseDepSpec>::Type>::value,
00198                          LicenseDepSpec, NoType<8u> >::Type,
00199                 typename Select<TypeListContains<VisitableTypeList, typename NodeType<ConditionalDepSpec>::Type>::value,
00200                          ConditionalDepSpec, NoType<9u> >::Type,
00201                 typename Select<TypeListContains<VisitableTypeList, typename NodeType<NamedSetDepSpec>::Type>::value,
00202                          NamedSetDepSpec, NoType<10u> >::Type,
00203                 typename Select<TypeListContains<VisitableTypeList, typename NodeType<PlainTextLabelDepSpec>::Type>::value,
00204                          PlainTextLabelDepSpec, NoType<11u> >::Type
00205                 > ItemFormatter;
00206 
00207         private:
00208             const std::tr1::shared_ptr<typename InnerNodeType<RootNode_>::Type> _root;
00209     };
00210 }
00211 
00212 #endif

Generated on Mon Sep 21 10:36:08 2009 for paludis by  doxygen 1.5.4