00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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