|
CXXR (C++ R)
|
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 */
1.7.3