File indexing completed on 2025-01-31 10:02:37
0001
0002
0003
0004
0005
0006
0007 #if !defined(BOOST_SPIRIT_X3_TST_MARCH_09_2007_0905AM)
0008 #define BOOST_SPIRIT_X3_TST_MARCH_09_2007_0905AM
0009
0010 #include <boost/call_traits.hpp>
0011 #include <boost/assert.hpp>
0012
0013 #include <string>
0014
0015 namespace boost { namespace spirit { namespace x3 { namespace detail
0016 {
0017
0018
0019
0020 template <typename Char, typename T>
0021 struct tst_node
0022 {
0023 tst_node(Char id)
0024 : id(id), data(0), lt(0), eq(0), gt(0)
0025 {
0026 }
0027
0028 template <typename Alloc>
0029 static void
0030 destruct_node(tst_node* p, Alloc* alloc)
0031 {
0032 if (p)
0033 {
0034 if (p->data)
0035 alloc->delete_data(p->data);
0036 destruct_node(p->lt, alloc);
0037 destruct_node(p->eq, alloc);
0038 destruct_node(p->gt, alloc);
0039 alloc->delete_node(p);
0040 }
0041 }
0042
0043 template <typename Alloc>
0044 static tst_node*
0045 clone_node(tst_node* p, Alloc* alloc)
0046 {
0047 if (p)
0048 {
0049 tst_node* clone = alloc->new_node(p->id);
0050 if (p->data)
0051 clone->data = alloc->new_data(*p->data);
0052 clone->lt = clone_node(p->lt, alloc);
0053 clone->eq = clone_node(p->eq, alloc);
0054 clone->gt = clone_node(p->gt, alloc);
0055 return clone;
0056 }
0057 return 0;
0058 }
0059
0060 template <typename Iterator, typename CaseCompare>
0061 static T*
0062 find(tst_node* start, Iterator& first, Iterator last, CaseCompare comp)
0063 {
0064 if (first == last)
0065 return 0;
0066
0067 Iterator i = first;
0068 Iterator latest = first;
0069 tst_node* p = start;
0070 T* found = 0;
0071
0072 while (p && i != last)
0073 {
0074 int32_t c = comp(*i,p->id);
0075 if (c == 0)
0076 {
0077 if (p->data)
0078 {
0079 found = p->data;
0080 latest = i;
0081 }
0082 p = p->eq;
0083 i++;
0084 }
0085 else if (c < 0)
0086 {
0087 p = p->lt;
0088 }
0089 else
0090 {
0091 p = p->gt;
0092 }
0093 }
0094
0095 if (found)
0096 first = ++latest;
0097 return found;
0098 }
0099
0100 template <typename Iterator, typename Alloc>
0101 static T*
0102 add(
0103 tst_node*& start
0104 , Iterator first
0105 , Iterator last
0106 , typename boost::call_traits<T>::param_type val
0107 , Alloc* alloc)
0108 {
0109 if (first == last)
0110 return 0;
0111
0112 tst_node** pp = &start;
0113 for (;;)
0114 {
0115 auto c = *first;
0116
0117 if (*pp == 0)
0118 *pp = alloc->new_node(c);
0119 tst_node* p = *pp;
0120
0121 if (c == p->id)
0122 {
0123 if (++first == last)
0124 {
0125 if (p->data == 0)
0126 p->data = alloc->new_data(val);
0127 return p->data;
0128 }
0129 pp = &p->eq;
0130 }
0131 else if (c < p->id)
0132 {
0133 pp = &p->lt;
0134 }
0135 else
0136 {
0137 pp = &p->gt;
0138 }
0139 }
0140 }
0141
0142 template <typename Iterator, typename Alloc>
0143 static void
0144 remove(tst_node*& p, Iterator first, Iterator last, Alloc* alloc)
0145 {
0146 if (p == 0 || first == last)
0147 return;
0148
0149 auto c = *first;
0150
0151 if (c == p->id)
0152 {
0153 if (++first == last)
0154 {
0155 if (p->data)
0156 {
0157 alloc->delete_data(p->data);
0158 p->data = 0;
0159 }
0160 }
0161 remove(p->eq, first, last, alloc);
0162 }
0163 else if (c < p->id)
0164 {
0165 remove(p->lt, first, last, alloc);
0166 }
0167 else
0168 {
0169 remove(p->gt, first, last, alloc);
0170 }
0171
0172 if (p->data == 0 && p->lt == 0 && p->eq == 0 && p->gt == 0)
0173 {
0174 alloc->delete_node(p);
0175 p = 0;
0176 }
0177 }
0178
0179 template <typename F>
0180 static void
0181 for_each(tst_node* p, std::basic_string<Char> prefix, F f)
0182 {
0183 if (p)
0184 {
0185 for_each(p->lt, prefix, f);
0186 std::basic_string<Char> s = prefix + p->id;
0187 for_each(p->eq, s, f);
0188 if (p->data)
0189 f(s, *p->data);
0190 for_each(p->gt, prefix, f);
0191 }
0192 }
0193
0194 Char id;
0195 T* data;
0196 tst_node* lt;
0197 tst_node* eq;
0198 tst_node* gt;
0199 };
0200 }}}}
0201
0202 #endif