/builddir/build/BUILD/infinispan-hotrod-cpp-6.2.1.Final-Source/include/infinispan/hotrod/portable.h

Go to the documentation of this file.
00001 #ifndef INFINISPAN_HOTROD_PORTABLE_H
00002 #define INFINISPAN_HOTROD_PORTABLE_H
00003 
00004 #include <cstdlib>
00005 #include <cstring>
00006 #include <string>
00007 #include <vector>
00008 #include <map>
00009 #include "infinispan/hotrod/ImportExport.h"
00010 
00018 namespace infinispan {
00019 namespace hotrod {
00020 namespace portable {
00021 
00022 #ifdef _MSC_VER
00023 #   define strncpy_safe strncpy_s    
00024 #else
00025 #   ifndef _TRUNCATE
00026 #       define _TRUNCATE ((size_t)-1)
00027 #   endif // _TRUNCATE
00028 static int strncpy_safe(char *dest, size_t numberOfElements, const char *src, size_t count) {    
00029     if (!count) return 0;
00030     if (!dest || !src || !numberOfElements) return -1;
00031     size_t end = count != _TRUNCATE && count < numberOfElements ? count : numberOfElements - 1;
00032     size_t i = 0;
00033     for (; i < end && src[i]; ++i) {
00034         dest[i] = src[i];        
00035     }
00036     if (!src[i] || end == count || count == _TRUNCATE) {
00037         dest[i] = '\0';
00038         return 0;
00039     }
00040     dest[0] = '\0';
00041     return -1;
00042 }
00043 #endif
00044 
00045 #define PORTABLE_STRING_BUF_SIZE 48
00046 
00047 class HR_EXTERN string {
00048 private:
00049     char m_buf[PORTABLE_STRING_BUF_SIZE];
00050     char *m_dynamic;
00051     size_t m_length;
00052 
00053     inline void init(const char *str, size_t len)
00054     {
00055         m_length = len;
00056         if (len < PORTABLE_STRING_BUF_SIZE) {
00057             strncpy_safe(m_buf, PORTABLE_STRING_BUF_SIZE, str, len);
00058             m_dynamic = 0;
00059         } else {
00060             m_dynamic = new char[len + 1];
00061             strncpy_safe(m_dynamic, len + 1, str, len);
00062         }
00063     }
00064 public:
00065     string(): m_dynamic(0), m_length(0)
00066     {
00067         m_buf[0] = 0;
00068     }
00069 
00070     string(const char *str)
00071     {
00072         init(str, strlen(str));
00073     }
00074 
00075     string(const std::string &str)
00076     {
00077         init(str.c_str(), str.length());
00078     }
00079 
00080     string(const string &o)
00081     {
00082         init(o.m_dynamic == 0 ? o.m_buf : o.m_dynamic, o.m_length);
00083     }
00084 
00085     inline string &operator=(const string &o)
00086     {
00087         if (m_dynamic != 0) delete[] m_dynamic;
00088         init(o.m_dynamic == 0 ? o.m_buf : o.m_dynamic, o.m_length);
00089         return *this;
00090     }
00091 
00092     inline ~string()
00093     {
00094         if (m_dynamic != 0) delete[] m_dynamic;
00095     }
00096 
00097     inline string &operator=(const std::string &str)
00098     {
00099         if (m_dynamic != 0) delete[] m_dynamic;
00100         init(str.c_str(), str.length());
00101         return *this;
00102     }
00103 
00104     inline const char *c_string() const
00105     {
00106         return m_dynamic == 0 ? m_buf : m_dynamic;
00107     }
00108 
00109     inline std::string std_string() const
00110     {
00111         return std::string(m_dynamic == 0 ? m_buf : m_dynamic);
00112     }
00113 
00114     static int cmp(const std::string &other, const string &str)
00115     {
00116         return cmp(other.c_str(), str);
00117     }
00118 
00119     static int cmp(const char *other, const string &str)
00120     {
00121         if (str.m_dynamic == 0) {
00122             return strncmp(other, str.m_buf, str.m_length);
00123         } else {
00124             return strncmp(other, str.m_dynamic, str.m_length);
00125         }
00126     }
00127 
00128     class convert {
00129     public:
00130         inline string operator()(const std::string &x)
00131         {
00132             return string(x);
00133         }
00134         inline std::string operator()(const string &x)
00135         {
00136             return x.std_string();
00137         }
00138     };
00139 };
00140 
00141 template<typename A, typename B> class converter {
00142     B operator()(const A &);
00143 };
00144 
00145 template<typename T> class identity {
00146     T operator()(const T &x) {
00147         return x;
00148     }
00149 };
00150 
00151 template<typename T> class vector
00152 {
00153 private:
00154     T *m_array;
00155     size_t m_size;
00156 
00157 public:
00158     class move_ref {
00159     friend class vector;
00160     private:
00161         vector<T> &m_ref;
00162         move_ref(vector<T> &ref): m_ref(ref) {}
00163     };
00164 
00165     vector(): m_array(0), m_size(0) {}
00166     vector(T *array, size_t s): m_array(array), m_size(s) {}
00167 
00168     template<typename Iterable> vector(const Iterable &v)
00169     {
00170         m_size = v.size();
00171         if (v.size() == 0) {
00172             m_array = 0;
00173         } else {
00174             m_array = new T[v.size()];
00175             size_t i = 0;
00176             for (typename Iterable::const_iterator it = v.begin(); it != v.end(); ++it) {
00177                 m_array[i++] = *it;
00178             }
00179         }
00180     }
00181 
00182     template<typename Iterable, typename Converter> vector(const Iterable &v, Converter convert)
00183     {
00184         m_size = v.size();
00185         if (v.size() == 0) {
00186             m_array = 0;
00187         } else {
00188             m_array = new T[v.size()];
00189             size_t i = 0;
00190             for (typename Iterable::const_iterator it = v.begin(); it != v.end(); ++it) {
00191                 m_array[i++] = convert(*it);
00192             }
00193         }
00194     }
00195 
00196     vector(const vector<T> &o)
00197     {
00198         m_size = o.m_size;
00199         if (m_size != 0) {
00200             m_array = new T[o.m_size];
00201             for (size_t i = 0; i < o.m_size; ++i) {
00202                 m_array[i] = o.m_array[i];
00203             }
00204         }
00205     }
00206     ~vector()
00207     {
00208         if (m_size != 0) delete[] m_array;
00209     }
00210 
00211     vector<T> &operator=(const vector<T> &o)
00212     {
00213         if (m_size < o.m_size) {
00214             delete[] m_array;
00215             m_array = new T[o.m_size];
00216         } else if (o.m_size == 0 && m_size != 0) {
00217             delete[] m_array;
00218         }
00219         m_size = o.m_size;
00220         for (size_t i = 0; i < o.m_size; ++i) {
00221             m_array[i] = o.m_array[i];
00222         }
00223         return *this;
00224     }
00225 
00226     vector(move_ref mr): m_array(mr.m_ref.m_array), m_size(mr.m_ref.m_size) {}
00227     vector<T> &operator=(move_ref mr)
00228     {
00229         if (m_size != 0) {
00230             delete[] m_array;
00231         }
00232         m_size = mr.m_ref.m_size;
00233         m_array = mr.m_ref.m_array;
00234         mr.m_ref.m_size = 0;
00235         mr.m_ref.m_array = 0;
00236         return *this;
00237     }
00242     move_ref move()
00243     {
00244         return move_ref(*this);
00245     }
00246 
00247     std::vector<T> std_vector() const
00248     {
00249         std::vector<T> v;
00250         v.reserve(m_size);
00251         for (size_t i = 0; i < m_size; ++i) {
00252             v.push_back(m_array[i]);
00253         }
00254         return v;
00255     }
00256 
00257     const T* data() const
00258     {
00259         return m_array;
00260     }
00261 
00262     size_t size() const
00263     {
00264         return m_size;
00265     }
00266 };
00267 
00268 template<typename K, typename V> class pair {
00269 public:
00270     K key;
00271     V value;
00272 };
00273 
00274 template<typename K, typename V> class map
00275 {
00276 private:
00277     typedef pair<K, V> my_pair;
00278 
00279     vector<my_pair> m_vec;
00280 
00281     /*template<typename K2, typename V2>
00282     static pair *to_array(const std::map<K2, V2> &m,
00283         K (*convertKey)(const K2 &),
00284         V (*convertValue)(const V2 &))
00285     {
00286         my_pair *data = new my_pair[m.size()];
00287         my_pair *dp = data;
00288         for (std::map<K2, V2>::const_iterator it = m.begin(); it != m.end(); ++it) {
00289             dp->key = convertKey(it->first);
00290             dp->value = convertValue(it->second);
00291             ++dp;
00292         }
00293         return data;
00294     }*/
00295 
00296     template<typename K2, typename KC, typename V2, typename VC>
00297     static my_pair *to_array(const std::map<K2, V2> &m,
00298         KC convertKey, VC convertValue)
00299     {
00300         my_pair *data = new my_pair[m.size()];
00301         my_pair *dp = data;
00302         for (typename std::map<K2, V2>::const_iterator it = m.begin(); it != m.end(); ++it) {
00303             dp->key = convertKey(it->first);
00304             dp->value = convertValue(it->second);
00305             ++dp;
00306         }
00307         return data;
00308     }
00309 
00310 public:
00311     class move_ref {
00312     friend class map;
00313     private:
00314         map<K, V> &m_ref;
00315         move_ref(map<K, V> &ref): m_ref(ref) {}
00316     };
00317 
00318     map() {}
00319 
00320 /*    template<typename K2, typename V2> map(const std::map<K2, V2> &m,
00321         K (*convertKey)(const K2 &) = identity<K>,
00322         V (*convertValue)(const V2 &) = identity<V>):
00323         m_vec(to_array(m, convertKey, convertValue), m.size()) {}*/
00324 
00325     map(const std::map<K, V> &m):
00326         m_vec(to_array(m, identity<K>(), identity<V>()), m.size()) {}
00327 
00328     template<typename K2, typename KC, typename V2, typename VC>
00329     map(const std::map<K2, V2> &m, KC convertKey = identity<K>(), VC convertValue = identity<V>()):
00330         m_vec(to_array(m, convertKey, convertValue), m.size()) {}
00331 
00332     map(const map<K, V> &o)
00333     {
00334         m_vec = o.m_vec;
00335     }
00336 
00337     map<K, V> &operator=(const map<K, V> &o)
00338     {
00339         m_vec = o.m_vec;
00340         return *this;
00341     }
00342 
00343     map(move_ref mr): m_vec(mr.m_ref.m_vec.move()) {}
00344     map<K, V> &operator=(move_ref mr)
00345     {
00346         m_vec = mr.m_ref.m_vec.move();
00347         return *this;
00348     }
00349     move_ref move()
00350     {
00351         return move_ref(*this);
00352     }
00353 
00354     std::map<K, V> std_map() const
00355     {
00356         std::map<K, V> m;
00357         for (size_t i = 0; i < m_vec.size(); ++i) {
00358             const my_pair *dp = m_vec.data() + i;
00359             m[dp->key] = dp->value;
00360         }
00361         return m;
00362     }
00363 
00364     template<typename K2, typename KC, typename V2, typename VC> std::map<K2, V2> std_map(
00365             KC convertKey, VC convertValue) const
00366     {
00367         std::map<K2, V2> m;
00368         for (size_t i = 0; i < m_vec.size(); ++i) {
00369             const my_pair *dp = m_vec.data() + i;
00370             m[convertKey(dp->key)] = convertValue(dp->value);
00371         }
00372         return m;
00373     }
00374 
00375     template<typename K2> const my_pair *get(K2 key, int (*cmp)(K2, const K &)) const {
00376         for (size_t i = 0; i < m_vec.size(); ++i) {
00377             const my_pair *dp = m_vec.data() + i;
00378             if (!cmp(key, dp->key)) return dp;
00379         }
00380         return 0;
00381     }
00382 
00383     const my_pair* data() const
00384     {
00385         return m_vec.data();
00386     }
00387 
00388     size_t size() const
00389     {
00390         return m_vec.size();
00391     }
00392 };
00393 
00394 /* Invasive reference counting */
00395 template<typename T> class counting_ptr;
00396 
00397 class counted_object {
00398 template<typename T> friend class counting_ptr;
00399 private:
00400     int m_counter;
00401 public:
00402     counted_object(): m_counter(0) {}
00403     virtual ~counted_object() {}
00404 };
00405 
00406 template<typename T> class counted_wrapper: public counted_object {
00407 private:
00408     T m_object;
00409 public:
00410     counted_wrapper(const T &o): m_object(o) {}
00411     T &operator()() { return m_object; }
00412 };
00413 
00414 template<typename T> class counting_ptr {
00415 public:
00416     typedef void (*destroy)(T *);
00417 private:
00418     counted_object *m_ptr;
00419     destroy m_destroy;
00420 
00421     inline void dec_and_destroy() {
00422         if (m_ptr != 0 && --(m_ptr->m_counter) == 0) {
00423             if (m_destroy == 0) {
00424                 delete m_ptr;
00425             } else {
00426                 m_destroy((T *)m_ptr);
00427             }
00428         }
00429     }
00430 public:
00431     counting_ptr(): m_ptr(0), m_destroy(0) {}
00432     counting_ptr(T *obj, destroy d = 0): m_ptr(obj), m_destroy(d) {
00433         counted_object *rc = obj; // no cast required
00434         if (rc != 0) {
00435             rc->m_counter++;
00436         }
00437     }
00438     ~counting_ptr() {
00439         dec_and_destroy();
00440     }
00441     counting_ptr(const counting_ptr &o): m_ptr(o.m_ptr), m_destroy(o.m_destroy) {
00442         if (m_ptr != 0) {
00443             m_ptr->m_counter++;
00444         }
00445     }
00446     counting_ptr &operator=(const counting_ptr &o) {
00447         dec_and_destroy();
00448         m_ptr = o.m_ptr;
00449         m_destroy = o.m_destroy;
00450         if (m_ptr != 0) {
00451             m_ptr->m_counter++;
00452         }
00453         return *this;
00454     }
00455     counting_ptr &operator=(T *rc) {
00456         return reset(rc, 0);
00457     }
00458     counting_ptr &reset(T *rc, destroy d) {
00459         dec_and_destroy();
00460         m_ptr = rc;
00461         m_destroy = d;
00462         if (rc != 0) {
00463             rc->m_counter++;
00464         }
00465         return *this;
00466     }
00467     T *get() {
00468         return (T *)m_ptr;
00469     }
00470     const T *get() const {
00471         return (T *)m_ptr;
00472     }
00473     T *operator->() {
00474         return (T *)m_ptr;
00475     }
00476     const T *operator->() const {
00477         return (const T *)m_ptr;
00478     }
00479 };
00480 
00481 template<typename T> class local_ptr {
00482 private:
00483     typedef void (*destroy)(T *);
00484     T *m_ptr;
00485     destroy m_destroy;
00486 public:
00487     local_ptr(): m_ptr(0), m_destroy(0) {}
00488     local_ptr(const local_ptr &): m_ptr(0), m_destroy(0) {} // copying does not persist value
00489     local_ptr &operator=(const local_ptr &) { return *this; }
00490     ~local_ptr() { if (m_ptr) m_destroy(m_ptr); }
00491     const T *get() const { return m_ptr; }
00492     T *get() { return m_ptr; }
00493     void set(T *ptr, void (*dtor)(T *)) {
00494         if (m_ptr) m_destroy(m_ptr);
00495         m_ptr = ptr;
00496         m_destroy = dtor;
00497     }
00498 };
00499 
00500 }}}
00501 
00502 #endif // INFINISPAN_HOTROD_PORTABLE_H

Generated on 25 Mar 2015 for JBoss Data Grid HotRod C++ Client by  doxygen 1.4.7