Changeset 568
- Timestamp:
- 06/24/08 11:03:12 (5 months ago)
- Files:
-
- trunk/rphp/runtime/var-test.cpp (modified) (8 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/rphp/runtime/var-test.cpp
r567 r568 2 2 /* 3 3 4 playing around with boost::variant, looking some somethingsuitable to store php vals4 playing around with boost::variant, to see if it's suitable to store php vals 5 5 6 6 */ 7 7 8 8 #include "boost/variant.hpp" 9 #include "boost/lexical_cast.hpp" 9 10 #include <iostream> 10 11 #include <typeinfo> … … 13 14 class php_hash { 14 15 private: 15 int x;16 int size; 16 17 public: 17 php_hash(int xvar) : x(xvar) { }18 php_hash(int sizevar) : size(sizevar) { } 18 19 19 20 php_hash(const php_hash& h) { 20 x = h.x;21 size = h.size; 21 22 } 22 int get x() const { return x; }23 int getSize() const { return size; } 23 24 24 25 }; … … 29 30 } 30 31 32 33 // using the c++ bool as a type seems to cause problems, so we implement php bool 34 // as an int. note that php integers are type long 35 // we also use in to decide if this value is NULL. unfortunately a null value would evaluate 36 // to true (in c++, since it's non 0). can we do this better? 37 typedef int p3state; 38 #define PFALSE 0 39 #define PTRUE 1 40 #define PNULL -1 41 31 42 // this would be the typedef for a generic php variable in our runtime 32 typedef boost::variant< int, std::string, double, php_hash> pvar; 33 34 typedef enum { PVAR_INT, PVAR_DOUBLE, PVAR_STRING, PVAR_HASH } pvartype; 35 43 typedef boost::variant< p3state, long, double, std::string, php_hash> pvar; 44 45 // used for determining type at runtime 46 typedef enum { PVAR_NULL, PVAR_BOOL, PVAR_LONG, PVAR_DOUBLE, PVAR_STRING, PVAR_HASH } pvartype; 47 48 // generic visitor which can be applied to any pvar 49 // correct method runs based on the appropriate type 36 50 class my_visitor : public boost::static_visitor<int> 37 51 { 38 52 public: 39 int operator()(int i) const 40 { 41 std::cout << "i see an int" << std::endl; 53 int operator()(const p3state &i) const 54 { 55 if (i >= 0) { 56 std::cout << "i see a bool" << std::endl; 57 } 58 else { 59 std::cout << "i see a null" << std::endl; 60 } 42 61 return i; 43 62 } 44 63 45 int operator()(double i) const 64 int operator()(const long &i) const 65 { 66 std::cout << "i see a long" << std::endl; 67 return i; 68 } 69 70 int operator()(const double &i) const 46 71 { 47 72 std::cout << "i see a float" << std::endl; … … 49 74 } 50 75 51 int operator()(const std::string & str) const76 int operator()(const std::string &str) const 52 77 { 53 78 std::cout << "i see a string" << std::endl; … … 55 80 } 56 81 57 int operator()(const php_hash & h) const82 int operator()(const php_hash &h) const 58 83 { 59 84 std::cout << "i see a php_hash" << std::endl; 60 return h.getx(); 61 } 62 63 }; 64 85 return 0; 86 } 87 88 }; 89 90 // a visitor for determining type 65 91 class type_checker : public boost::static_visitor<int> 66 92 { 67 93 public: 68 pvartype operator()( inti) const69 { 70 return PVAR_ INT;71 } 72 73 pvartype operator()( doublei) const94 pvartype operator()(const long &i) const 95 { 96 return PVAR_LONG; 97 } 98 99 pvartype operator()(const double &i) const 74 100 { 75 101 return PVAR_DOUBLE; 76 102 } 77 103 78 pvartype operator()(const std::string & str) const104 pvartype operator()(const std::string &str) const 79 105 { 80 106 return PVAR_STRING; 81 107 } 82 108 83 pvartype operator()(const php_hash & h) const109 pvartype operator()(const php_hash &h) const 84 110 { 85 111 return PVAR_HASH; 86 112 } 87 113 114 pvartype operator()(const p3state &h) const 115 { 116 return (h >= 0) ? PVAR_BOOL : PVAR_NULL; 117 } 118 119 }; 120 121 // a visitor for converting to a num 122 class convert_to_num_visitor : public boost::static_visitor<> 123 { 124 protected: 125 pvar &var; 126 public: 127 convert_to_num_visitor(pvar &v) : var(v) {} 128 129 void operator()(const std::string &a) const { 130 try { 131 var = boost::lexical_cast<long>(a); 132 } catch(boost::bad_lexical_cast &) { 133 var = 0l; 134 } 135 } 136 137 void operator()(const double &i) const 138 { 139 // nothing, already numeric 140 } 141 142 void operator()(const php_hash &h) const 143 { 144 var = (long)h.getSize(); 145 } 146 147 void operator()(const p3state &h) const 148 { 149 (h <= 0) ? var = 0l : var = 1l; 150 } 151 152 void operator()(const long &a) const { 153 // Do nothing - already correct type 154 } 88 155 }; 89 156 … … 93 160 { 94 161 pvar u; 162 163 // string 95 164 u = "hello world there"; 96 165 … … 98 167 int result = boost::apply_visitor( my_visitor(), u ); 99 168 100 u = 15; 101 102 std::cout << u << std::endl; 103 result = boost::apply_visitor( my_visitor(), u ); 104 169 // long 170 u = 15l; 171 172 std::cout << u << std::endl; 173 result = boost::apply_visitor( my_visitor(), u ); 174 175 // float 105 176 u = 2.3123; 106 177 107 178 std::cout << u << std::endl; 108 179 result = boost::apply_visitor( my_visitor(), u ); 180 181 // bool 182 u = PTRUE; 183 184 std::cout << u << std::endl; 185 result = boost::apply_visitor( my_visitor(), u ); 186 187 if (boost::get<p3state>(u) == PTRUE) { 188 std::cout << "the bool was true" << std::endl; 189 } 190 191 // null 192 u = PNULL; 193 194 std::cout << u << std::endl; 195 result = boost::apply_visitor( my_visitor(), u ); 196 197 // php hash 198 php_hash h(5); 199 std::cout << h; 200 u = h; 201 std::cout << u << std::endl; 202 203 result = boost::apply_visitor( my_visitor(), u ); 204 205 //// 109 206 110 207 // type checking? 111 208 int pt = boost::apply_visitor( type_checker(), u ); 112 209 switch (pt) { 113 case PVAR_ STRING:114 std::cout << "found a string" << std::endl;210 case PVAR_HASH: 211 std::cout << "found a hash" << std::endl; 115 212 break; 116 213 case PVAR_DOUBLE: … … 120 217 std::cout << "woops, what type was it?" << std::endl; 121 218 } 122 123 php_hash h(5); 124 std::cout << h; 125 u = h; 126 std::cout << u << std::endl; 127 128 result = boost::apply_visitor( my_visitor(), u ); 129 130 //std::cout << result << std::endl; // output: 11 (i.e., length of "hello world") 131 132 // output is ugly, it also might not be available everywhere 219 // RTTI: output is ugly, it also might not be available everywhere 133 220 std::cout << typeid( u ).name() << std::endl; 221 222 //// 223 224 // type conversion 225 std::cout << "type conversion:" << std::endl; 226 u = "55"; 227 boost::apply_visitor( my_visitor(), u ); 228 boost::apply_visitor( convert_to_num_visitor(u), u ); 229 boost::apply_visitor( my_visitor(), u ); 230 std::cout << "final: " << u << std::endl; 231 134 232 }
