CXXR (C++ R)

CachedString.h

Go to the documentation of this file.
00001 /*CXXR $Id: CachedString.h 1275 2012-03-17 14:01:29Z arr $
00002  *CXXR
00003  *CXXR This file is part of CXXR, a project to refactor the R interpreter
00004  *CXXR into C++.  It may consist in whole or in part of program code and
00005  *CXXR documentation taken from the R project itself, incorporated into
00006  *CXXR CXXR (and possibly MODIFIED) under the terms of the GNU General Public
00007  *CXXR Licence.
00008  *CXXR 
00009  *CXXR CXXR is Copyright (C) 2008-12 Andrew R. Runnalls, subject to such other
00010  *CXXR copyrights and copyright restrictions as may be stated below.
00011  *CXXR 
00012  *CXXR CXXR is not part of the R project, and bugs and other issues should
00013  *CXXR not be reported via r-bugs or other R project channels; instead refer
00014  *CXXR to the CXXR website.
00015  *CXXR */
00016 
00017 /*
00018  *  R : A Computer Language for Statistical Data Analysis
00019  *  Copyright (C) 1995, 1996  Robert Gentleman and Ross Ihaka
00020  *  Copyright (C) 1999-2006   The R Development Core Team.
00021  *
00022  *  This program is free software; you can redistribute it and/or modify
00023  *  it under the terms of the GNU General Public License as published by
00024  *  the Free Software Foundation; either version 2.1 of the License, or
00025  *  (at your option) any later version.
00026  *
00027  *  This program is distributed in the hope that it will be useful,
00028  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00029  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00030  *  GNU Lesser General Public License for more details.
00031  *
00032  *  You should have received a copy of the GNU General Public License
00033  *  along with this program; if not, a copy is available at
00034  *  http://www.r-project.org/Licenses/
00035  */
00036 
00041 #ifndef CACHEDSTRING_H
00042 #define CACHEDSTRING_H
00043 
00044 #include "CXXR/String.h"
00045 
00046 #ifdef __cplusplus
00047 
00048 #include <tr1/unordered_map>
00049 #include <string>
00050 
00051 #include "CXXR/Allocator.hpp"
00052 #include "CXXR/SchwarzCounter.hpp"
00053 
00054 namespace CXXR {
00060     class CachedString : public String {
00061     public:
00065         static CachedString* blank()
00066         {
00067             return s_blank;
00068         }
00069 
00091         static CachedString* obtain(const std::string& str,
00092                                     cetype_t encoding = CE_NATIVE);
00093 
00098         static const char* staticTypeName()
00099         {
00100             return "char (cached)";
00101         }
00102 
00107         const std::string& stdstring() const
00108         {
00109             return m_key_val_pr->first.first;
00110         }
00111 
00112         // Virtual function of RObject:
00113         const char* typeName() const;
00114     private:
00115         // The first element of the key is the text, the second
00116         // element the encoding:
00117         typedef std::pair<std::string, cetype_t> key;
00118 
00119         // Hashing is based simply on the text of the key, not on its
00120         // encoding:
00121         class Hasher : public std::unary_function<key, std::size_t> {
00122         public:
00123             std::size_t operator()(const key& k) const
00124             {
00125                 return s_string_hasher(k.first);
00126             }
00127         private:
00128             static std::tr1::hash<std::string> s_string_hasher;
00129         };
00130 
00131         // The cache is implemented as a mapping from keys to pointers
00132         // to CachedString objects.  Each CachedString simply contains
00133         // a pointer locating its entry within the cache.
00134         typedef
00135         std::tr1::unordered_map<key, CachedString*, Hasher,
00136                                 std::equal_to<key>,
00137                                 CXXR::Allocator<std::pair<const key,
00138                                                           CachedString*> >
00139                                 > map;
00140 
00141         static map* s_cache;
00142         static CachedString* s_blank;
00143 
00144         map::value_type* m_key_val_pr;
00145         mutable Symbol* m_symbol;  // Pointer to the Symbol object identified
00146           // by this CachedString, or a null pointer if none.
00147 
00148         explicit CachedString(map::value_type* key_val_pr)
00149             : String(key_val_pr->first.first.size(), key_val_pr->first.second),
00150             m_key_val_pr(key_val_pr), m_symbol(0)
00151         {
00152             setCString(key_val_pr->first.first.c_str());
00153         }
00154 
00155         // Not implemented.  Declared to prevent
00156         // compiler-generated versions:
00157         CachedString(const CachedString&);
00158         CachedString& operator=(const CachedString&);
00159 
00160         // Declared private to ensure that CachedString objects are
00161         // allocated only using 'new'.
00162         ~CachedString();
00163 
00164         static void cleanup();
00165 
00166         // Initialize the static data members:
00167         static void initialize();
00168 
00169         friend class SchwarzCounter<CachedString>;
00170         friend class Symbol;
00171     };
00172 }  // namespace CXXR
00173 
00174 namespace {
00175     CXXR::SchwarzCounter<CXXR::CachedString> cachedstring_schwarz_ctr;
00176 }
00177 
00178 extern "C" {
00179 
00180 #endif /* __cplusplus */
00181 
00188 #ifndef __cplusplus
00189     int IS_CACHED(SEXP x);
00190 #else
00191     inline int IS_CACHED(SEXP x)
00192     {
00193         // Use explicit namespace qualification to avoid ambiguities:
00194         const CXXR::String* str = CXXR::SEXP_downcast<const CXXR::String*>(x);
00195         return (dynamic_cast<const CXXR::CachedString*>(str) != 0);
00196     }
00197 #endif
00198 
00210 #ifndef __cplusplus
00211     SEXP Rf_mkChar(const char * str);
00212 #else
00213     inline SEXP Rf_mkChar(const char * str)
00214     {
00215         return CXXR::CachedString::obtain(str);
00216     }
00217 #endif
00218     
00234 #ifndef __cplusplus
00235     SEXP Rf_mkCharCE(const char * str, cetype_t encoding);
00236 #else
00237     inline SEXP Rf_mkCharCE(const char * str, cetype_t encoding)
00238     {
00239         return CXXR::CachedString::obtain(str, encoding);
00240     }
00241 #endif
00242 
00260     SEXP Rf_mkCharLenCE(const char* text, int length, cetype_t encoding);
00261 
00274 #ifndef __cplusplus
00275     SEXP Rf_mkCharLen(const char* text, int length);
00276 #else
00277     inline SEXP Rf_mkCharLen(const char* text, int length)
00278     {
00279         return Rf_mkCharLenCE(text, length, CE_NATIVE);
00280     }
00281 #endif
00282 
00283 #ifdef __cplusplus
00284 }  // extern "C"
00285 #endif
00286 
00287 #endif /* CACHEDSTRING_H */