00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00036 #ifndef _depends_details_visitors_h
00037 #define _depends_details_visitors_h
00038
00039 #include <iterator>
00040 #include "ScopedFlag.h"
00041 #include "CircularReferenceException.h"
00042
00043 namespace Depends
00044 {
00045 namespace Details
00046 {
00048 struct EmptyFunctor
00049 {
00050 template <class NodeType, class DataType>
00051 EmptyFunctor & operator()(NodeType * node, DataType & data)
00052 {
00053 return *this;
00054 }
00055
00056 operator bool()
00057 {
00058 return false;
00059 }
00060 };
00061
00063 struct IncScoreFunctor
00064 {
00065 template <class NodeType, class DataType>
00066 IncScoreFunctor & operator()(NodeType * node, DataType & data)
00067 {
00068 node->score_ += data;
00069
00070 return *this;
00071 }
00072
00073 operator bool()
00074 {
00075 return true;
00076 }
00077 };
00078
00080 struct DecScoreFunctor
00081 {
00082 template <class NodeType, class DataType>
00083 DecScoreFunctor & operator()(NodeType * node, DataType & data)
00084 {
00085 node->score_ -= data;
00086
00087 return *this;
00088 }
00089
00090 operator bool()
00091 {
00092 return true;
00093 }
00094 };
00095
00097 struct RetrieveTargets
00098 {
00099 template < class NodeType, class DataType >
00100 RetrieveTargets & operator()(NodeType * node, DataType & data)
00101 {
00102 data->insert(node->value_);
00103
00104 return *this;
00105 }
00106
00107 operator bool()
00108 {
00109 return true;
00110 }
00111 };
00112
00114 template <class NodeType, class BinaryFunction = EmptyFunctor, class DataType = void*>
00115 struct NodeVisitor
00116 {
00117 NodeVisitor()
00118 {
00119 }
00120
00121 NodeVisitor(const BinaryFunction & binary_function, const DataType data)
00122 : binary_function_(binary_function),
00123 data_(data)
00124 {
00125 }
00126
00127 NodeVisitor & operator()(NodeType * node)
00128 {
00129 if (node->flags_ & NodeType::VISITED)
00130 throw CircularReferenceException();
00131 if (binary_function_)
00132 binary_function_(node, data_);
00133 {
00134 ScopedFlag<NodeType> scoped_flag(node, NodeType::VISITED);
00135 std::for_each(
00136 node->targets_.begin(),
00137 node->targets_.end(),
00138 *this);
00139 }
00140 return *this;
00141 }
00142
00143 BinaryFunction binary_function_;
00144 DataType data_;
00145 };
00146 }
00147 }
00148
00149 #endif
00150