Changeset 568

Show
Ignore:
Timestamp:
06/24/08 11:03:12 (5 months ago)
Author:
weyrick
Message:

all basic types defined

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/rphp/runtime/var-test.cpp

    r567 r568  
    22/* 
    33 
    4 playing around with boost::variant, looking some something suitable to store php vals 
     4playing around with boost::variant, to see if it's suitable to store php vals 
    55 
    66*/ 
    77 
    88#include "boost/variant.hpp" 
     9#include "boost/lexical_cast.hpp" 
    910#include <iostream> 
    1011#include <typeinfo> 
     
    1314class php_hash { 
    1415    private: 
    15         int x
     16        int size
    1617    public: 
    17         php_hash(int xvar) : x(xvar) { } 
     18        php_hash(int sizevar) : size(sizevar) { } 
    1819 
    1920        php_hash(const php_hash& h) { 
    20             x = h.x
     21            size = h.size
    2122        } 
    22         int getx() const { return x; } 
     23        int getSize() const { return size; } 
    2324 
    2425}; 
     
    2930} 
    3031 
     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? 
     37typedef int p3state; 
     38#define PFALSE 0 
     39#define PTRUE  1 
     40#define PNULL -1 
     41 
    3142// 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  
     43typedef boost::variant< p3state, long, double, std::string, php_hash> pvar; 
     44 
     45// used for determining type at runtime 
     46typedef 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 
    3650class my_visitor : public boost::static_visitor<int> 
    3751{ 
    3852public: 
    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        } 
    4261        return i; 
    4362    } 
    4463 
    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 
    4671    { 
    4772        std::cout << "i see a float" << std::endl; 
     
    4974    } 
    5075 
    51     int operator()(const std::string & str) const 
     76    int operator()(const std::string &str) const 
    5277    { 
    5378        std::cout << "i see a string" << std::endl; 
     
    5580    } 
    5681 
    57     int operator()(const php_hash & h) const 
     82    int operator()(const php_hash &h) const 
    5883    { 
    5984        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 
    6591class type_checker : public boost::static_visitor<int> 
    6692{ 
    6793public: 
    68     pvartype operator()(int i) const 
    69     { 
    70         return PVAR_INT
    71     } 
    72  
    73     pvartype operator()(double i) const 
     94    pvartype operator()(const long &i) const 
     95    { 
     96        return PVAR_LONG
     97    } 
     98 
     99    pvartype operator()(const double &i) const 
    74100    { 
    75101                return PVAR_DOUBLE; 
    76102    } 
    77103 
    78     pvartype operator()(const std::string & str) const 
     104    pvartype operator()(const std::string &str) const 
    79105    { 
    80106        return PVAR_STRING; 
    81107    } 
    82108 
    83     pvartype operator()(const php_hash & h) const 
     109    pvartype operator()(const php_hash &h) const 
    84110    { 
    85111        return PVAR_HASH; 
    86112    } 
    87113 
     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 
     122class convert_to_num_visitor : public boost::static_visitor<> 
     123{ 
     124protected: 
     125  pvar &var; 
     126public: 
     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  } 
    88155}; 
    89156 
     
    93160{ 
    94161    pvar u; 
     162 
     163    // string 
    95164    u = "hello world there"; 
    96165 
     
    98167    int result = boost::apply_visitor( my_visitor(), u ); 
    99168 
    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 
    105176    u = 2.3123; 
    106177 
    107178    std::cout << u << std::endl; 
    108179    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    //// 
    109206 
    110207    // type checking? 
    111208    int pt = boost::apply_visitor( type_checker(), u ); 
    112209    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; 
    115212        break; 
    116213    case PVAR_DOUBLE: 
     
    120217        std::cout << "woops, what type was it?" << std::endl; 
    121218    } 
    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 
    133220    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 
    134232}