CXXR (C++ R)
Provenance.hpp
Go to the documentation of this file.
1 /*CXXR $Id: Provenance.hpp 1403 2013-09-12 07:46:53Z 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-13 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 /* This file incorporates material Copyright (C) Chris A. Silles 2009-12.
18  */
19 
20 /*
21  * This program is free software; you can redistribute it and/or modify
22  * it under the terms of the GNU General Public License as published by
23  * the Free Software Foundation; either version 2.1 of the License, or
24  * (at your option) any later version.
25  *
26  * This program is distributed in the hope that it will be useful,
27  * but WITHOUT ANY WARRANTY; without even the implied warranty of
28  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29  * GNU Lesser General Public License for more details.
30  *
31  * You should have received a copy of the GNU General Public License
32  * along with this program; if not, a copy is available at
33  * http://www.r-project.org/Licenses/
34  */
35 
41 #ifndef PROVENANCE_HPP
42 #define PROVENANCE_HPP 1
43 
44 #include <sys/time.h>
45 #include <ctime>
46 #include <set>
47 #include <boost/serialization/access.hpp>
48 #include <boost/serialization/base_object.hpp>
49 #include <boost/serialization/nvp.hpp>
50 #include <boost/serialization/split_member.hpp>
51 
53 #include "CXXR/Expression.h"
54 #include "CXXR/GCEdge.hpp"
55 #include "CXXR/GCStackRoot.hpp"
56 #include "CXXR/RObject.h"
57 #include "CXXR/StringVector.h"
58 #include "CXXR/Symbol.h"
59 
60 namespace CXXR {
95  class Provenance : public GCNode {
96  public:
102  class CompTime {
103  public:
113  bool operator()(const Provenance* lhs, const Provenance* rhs) const
114  {
115  return (lhs->m_timestamp.tv_sec == rhs->m_timestamp.tv_sec) ?
116  (lhs->m_timestamp.tv_usec < rhs->m_timestamp.tv_usec) :
117  (lhs->m_timestamp.tv_sec < rhs->m_timestamp.tv_sec);
118  }
119  };
120 
124  typedef std::set<const Provenance*, Provenance::CompTime> Set;
125 
134  Provenance(const Symbol* sym, const CommandChronicle* chron);
135 
136  ~Provenance()
137  {
138  announceDeath(); // Necessary house-keeping
139  }
140 
150  static Set* ancestors(const Set& roots);
151 
157  const Set& children() const
158  {
159  return m_children;
160  }
161 
168  {
169  return m_chronicle;
170  }
171 
177  const RObject* command() const
178  {
179  return m_chronicle->command();
180  }
181 
191  static Set* descendants(const Set& roots);
192 
202  const String* getTime() const;
203 
209  std::pair<CommandChronicle::ParentVector::const_iterator,
210  CommandChronicle::ParentVector::const_iterator>
211  parents() const;
212 
217  const Symbol* symbol() const
218  {
219  return m_symbol;
220  }
221 
227  const RObject* value() const
228  {
229  return m_value;
230  }
231 
236  bool isXenogenous() const
237  {
238  return m_xenogenous;
239  }
240 
249  unsigned int serialNumber() const
250  {
251  return m_serial;
252  }
253 
264  void setXenogenous(const RObject* value);
265 
272  double timestamp() const;
273 
274  // Virtual functions of GCNode:
275  void detachReferents();
276  void visitReferents(const_visitor*) const;
277  private:
278  friend class boost::serialization::access;
279 
280  static unsigned int s_next_serial;
281 
282  mutable Set m_children;
283  struct timeval m_timestamp;
284 
285  unsigned int m_serial; // Within a session each Provenance
286  // object is given a unique serial number. This serial
287  // number is not preserved during serialisation.
288 
289  unsigned int m_num_parents;
290  GCEdge<const Symbol> m_symbol;
291  GCEdge<const CommandChronicle> m_chronicle;
292  GCEdge<const RObject> m_value;
293  bool m_xenogenous;
294 
295  // Do away with compiler-generated copy constructor
296  Provenance(const Provenance&);
297 
298  void announceBirth();
299 
300  void announceDeath();
301 
302  void deregisterChild(const Provenance* child) const
303  {
304  m_children.erase(child);
305  }
306 
307  void registerChild(const Provenance* child) const
308  {
309  m_children.insert(child);
310  }
311 
312  template <class Archive>
313  void load(Archive& ar, const unsigned int version);
314 
315  template <class Archive>
316  void save(Archive& ar, const unsigned int version) const;
317 
318  template <class Archive>
319  void serialize(Archive & ar, const unsigned int version) {
320  boost::serialization::split_member(ar, *this, version);
321  }
322  };
323 } // namespace CXXR
324 
325 BOOST_CLASS_EXPORT_KEY(CXXR::Provenance)
326 
327 namespace boost {
328  namespace serialization {
346  template<class Archive>
347  void load_construct_data(Archive& ar, CXXR::Provenance* prov,
348  const unsigned int version)
349  {
350  using namespace CXXR;
352  GCNPTR_SERIALIZE(ar, symbol);
354  GCNPTR_SERIALIZE(ar, chronicle);
355  new (prov) Provenance(symbol, chronicle);
356  }
357 
378  template<class Archive>
379  void save_construct_data(Archive& ar, const CXXR::Provenance* prov,
380  const unsigned int version)
381  {
382  using namespace CXXR;
383  const Symbol* symbol = prov->symbol();
384  GCNPTR_SERIALIZE(ar, symbol);
385  const CommandChronicle* chronicle = prov->chronicle();
386  GCNPTR_SERIALIZE(ar, chronicle);
387  }
388  } // namespace serialization
389 } // namespace boost
390 
391 // ***** Implementation of non-inlined templated members *****
392 
393 template <class Archive>
394 void CXXR::Provenance::load(Archive& ar, const unsigned int version)
395 {
396  ar >> BOOST_SERIALIZATION_BASE_OBJECT_NVP(GCNode);
397  ar >> boost::serialization::make_nvp("sec", m_timestamp.tv_sec);
398  ar >> boost::serialization::make_nvp("usec", m_timestamp.tv_usec);
399  ar >> BOOST_SERIALIZATION_NVP(m_num_parents);
400  GCNPTR_SERIALIZE(ar, m_value);
401  ar >> BOOST_SERIALIZATION_NVP(m_xenogenous);
402 
403  announceBirth();
404 }
405 
406 template <class Archive>
407 void CXXR::Provenance::save(Archive& ar, const unsigned int version) const
408 {
409  ar << BOOST_SERIALIZATION_BASE_OBJECT_NVP(GCNode);
410  ar << boost::serialization::make_nvp("sec", m_timestamp.tv_sec);
411  ar << boost::serialization::make_nvp("usec", m_timestamp.tv_usec);
412  ar << BOOST_SERIALIZATION_NVP(m_num_parents);
413  GCNPTR_SERIALIZE(ar, m_value);
414  ar << BOOST_SERIALIZATION_NVP(m_xenogenous);
415 }
416 
417 #endif