CXXR (C++ R) API
CachedString.h
Go to the documentation of this file.
1 /*CXXR $Id: CachedString.h 1275 2012-03-17 14:01:29Z arr $
2  *CXXR
3  *CXXR This file is part of CXXR, a project to refactor the R interpreter
4  *CXXR into C++. It may consist in whole or in part of program code and
5  *CXXR documentation taken from the R project itself, incorporated into
6  *CXXR CXXR (and possibly MODIFIED) under the terms of the GNU General Public
7  *CXXR Licence.
8  *CXXR
9  *CXXR CXXR is Copyright (C) 2008-12 Andrew R. Runnalls, subject to such other
10  *CXXR copyrights and copyright restrictions as may be stated below.
11  *CXXR
12  *CXXR CXXR is not part of the R project, and bugs and other issues should
13  *CXXR not be reported via r-bugs or other R project channels; instead refer
14  *CXXR to the CXXR website.
15  *CXXR */
16 
17 /*
18  * R : A Computer Language for Statistical Data Analysis
19  * Copyright (C) 1995, 1996 Robert Gentleman and Ross Ihaka
20  * Copyright (C) 1999-2006 The R Development Core Team.
21  *
22  * This program is free software; you can redistribute it and/or modify
23  * it under the terms of the GNU General Public License as published by
24  * the Free Software Foundation; either version 2.1 of the License, or
25  * (at your option) any later version.
26  *
27  * This program is distributed in the hope that it will be useful,
28  * but WITHOUT ANY WARRANTY; without even the implied warranty of
29  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
30  * GNU Lesser General Public License for more details.
31  *
32  * You should have received a copy of the GNU General Public License
33  * along with this program; if not, a copy is available at
34  * http://www.r-project.org/Licenses/
35  */
36 
41 #ifndef CACHEDSTRING_H
42 #define CACHEDSTRING_H
43 
44 #include "CXXR/String.h"
45 
46 #ifdef __cplusplus
47 
48 #include <tr1/unordered_map>
49 #include <string>
50 
51 #include "CXXR/Allocator.hpp"
52 #include "CXXR/SchwarzCounter.hpp"
53 
54 namespace CXXR {
60  class CachedString : public String {
61  public:
65  static CachedString* blank()
66  {
67  return s_blank;
68  }
69 
91  static CachedString* obtain(const std::string& str,
92  cetype_t encoding = CE_NATIVE);
93 
98  static const char* staticTypeName()
99  {
100  return "char (cached)";
101  }
102 
107  const std::string& stdstring() const
108  {
109  return m_key_val_pr->first.first;
110  }
111 
112  // Virtual function of RObject:
113  const char* typeName() const;
114  private:
115  // The first element of the key is the text, the second
116  // element the encoding:
117  typedef std::pair<std::string, cetype_t> key;
118 
119  // Hashing is based simply on the text of the key, not on its
120  // encoding:
121  class Hasher : public std::unary_function<key, std::size_t> {
122  public:
123  std::size_t operator()(const key& k) const
124  {
125  return s_string_hasher(k.first);
126  }
127  private:
128  static std::tr1::hash<std::string> s_string_hasher;
129  };
130 
131  // The cache is implemented as a mapping from keys to pointers
132  // to CachedString objects. Each CachedString simply contains
133  // a pointer locating its entry within the cache.
134  typedef
135  std::tr1::unordered_map<key, CachedString*, Hasher,
136  std::equal_to<key>,
137  CXXR::Allocator<std::pair<const key,
138  CachedString*> >
139  > map;
140 
141  static map* s_cache;
142  static CachedString* s_blank;
143 
144  map::value_type* m_key_val_pr;
145  mutable Symbol* m_symbol; // Pointer to the Symbol object identified
146  // by this CachedString, or a null pointer if none.
147 
148  explicit CachedString(map::value_type* key_val_pr)
149  : String(key_val_pr->first.first.size(), key_val_pr->first.second),
150  m_key_val_pr(key_val_pr), m_symbol(0)
151  {
152  setCString(key_val_pr->first.first.c_str());
153  }
154 
155  // Not implemented. Declared to prevent
156  // compiler-generated versions:
157  CachedString(const CachedString&);
158  CachedString& operator=(const CachedString&);
159 
160  // Declared private to ensure that CachedString objects are
161  // allocated only using 'new'.
162  ~CachedString();
163 
164  static void cleanup();
165 
166  // Initialize the static data members:
167  static void initialize();
168 
169  friend class SchwarzCounter<CachedString>;
170  friend class Symbol;
171  };
172 } // namespace CXXR
173 
174 namespace {
175  CXXR::SchwarzCounter<CXXR::CachedString> cachedstring_schwarz_ctr;
176 }
177 
178 extern "C" {
179 
180 #endif /* __cplusplus */
181 
188 #ifndef __cplusplus
189  int IS_CACHED(SEXP x);
190 #else
191  inline int IS_CACHED(SEXP x)
192  {
193  // Use explicit namespace qualification to avoid ambiguities:
194  const CXXR::String* str = CXXR::SEXP_downcast<const CXXR::String*>(x);
195  return (dynamic_cast<const CXXR::CachedString*>(str) != 0);
196  }
197 #endif
198 
210 #ifndef __cplusplus
211  SEXP Rf_mkChar(const char * str);
212 #else
213  inline SEXP Rf_mkChar(const char * str)
214  {
215  return CXXR::CachedString::obtain(str);
216  }
217 #endif
218 
234 #ifndef __cplusplus
235  SEXP Rf_mkCharCE(const char * str, cetype_t encoding);
236 #else
237  inline SEXP Rf_mkCharCE(const char * str, cetype_t encoding)
238  {
239  return CXXR::CachedString::obtain(str, encoding);
240  }
241 #endif
242 
260  SEXP Rf_mkCharLenCE(const char* text, int length, cetype_t encoding);
261 
274 #ifndef __cplusplus
275  SEXP Rf_mkCharLen(const char* text, int length);
276 #else
277  inline SEXP Rf_mkCharLen(const char* text, int length)
278  {
279  return Rf_mkCharLenCE(text, length, CE_NATIVE);
280  }
281 #endif
282 
283 #ifdef __cplusplus
284 } // extern "C"
285 #endif
286 
287 #endif /* CACHEDSTRING_H */