newimage
 
Loading...
Searching...
No Matches
lazy.h
1/* Lazy evaluation support
2
3 Mark Jenkinson, FMRIB Image Analysis Group
4
5 Copyright (C) 2000 University of Oxford */
6
7/* CCOPYRIGHT */
8
9#if !defined(__lazy_h)
10#define __lazy_h
11
12#include <iostream>
13#include <map>
14#include <cstdlib>
15
16namespace LAZY {
17
18
19typedef std::map<unsigned int,bool,std::less<unsigned int> > mapclass;
20typedef std::map<unsigned int,bool,std::less<unsigned int> >::iterator mapiterator;
21
22
23//-------------------------------------------------------------------------//
24
25template <class T, class S>
26class lazy {
27private:
28 mutable T storedval;
29 unsigned int tag;
30 const S *iptr;
31 T (*calc_fn)(const S &);
32
33private:
34 const T& value() const;
35 T calculate_val() const { return (*calc_fn)(*iptr); }
36
37public:
38 lazy() { tag = 0; }
39 void init(const S *, T (*fnptr)(const S &));
40 void copy(const lazy &, const S *);
41
42 const T& force_recalculation() const;
43
44 const T& operator() () const { return this->value(); }
45};
46
47
48//-------------------------------------------------------------------------//
49
51 template <class T, class S> friend class lazy;
52private:
53 mutable bool validflag;
54 mutable mapclass validcache;
55 mutable unsigned int tagnum;
56
57private:
58 unsigned int getnewtag() const { return tagnum++; }
59
60 bool is_whole_cache_valid() const
61 { return validflag; }
62
63 bool is_cache_entry_valid(const unsigned int tag) const
64 { return validcache[tag]; }
65 void set_cache_entry_validity(const unsigned int tag, const bool newflag) const
66 { validcache[tag] = newflag; }
67
68 void invalidate_whole_cache() const;
69
70public:
72 void copylazymanager(const lazymanager &);
73 void set_whole_cache_validity(const bool newflag) const
74 { validflag = newflag; }
75};
76
77
78//-------------------------------------------------------------------------//
79
80// Body of lazy member functions (put here as cannot simply separate
81// templated definitions into seperate source files if building a library)
82
83
84
85template <class T, class S>
86const T& lazy<T,S>::value() const
87 {
88 if ( (iptr == 0) || (tag==0) ) {
89 std::cerr << "Error: uninitialized lazy evaluation class" << std::endl;
90 exit(-1);
91 }
92 if (! iptr->is_whole_cache_valid() ) {
93 iptr->invalidate_whole_cache();
94 iptr->set_whole_cache_validity(true);
95 }
96 if (! iptr->is_cache_entry_valid(tag)) {
97 //cerr << "Calculating value" << endl;
98 storedval = calculate_val();
99 iptr->set_cache_entry_validity(tag,true);
100 }
101 return storedval;
102 }
103
104
105template <class T, class S>
106const T& lazy<T,S>::force_recalculation() const
107 {
108 if ( (iptr == 0) || (tag==0) ) {
109 std::cerr << "Error: uninitialized lazy evaluation class" << std::endl;
110 exit(-1);
111 }
112 // still process the whole cache vailidity so that this calculation
113 // can get cached correctly
114 if (! iptr->is_whole_cache_valid() ) {
115 iptr->invalidate_whole_cache();
116 iptr->set_whole_cache_validity(true);
117 }
118
119 storedval = calculate_val();
120 iptr->set_cache_entry_validity(tag,true);
121
122 return storedval;
123 }
124
125
126template <class T, class S>
127void lazy<T,S>::init(const S *ip, T (*fnptr)(const S &))
128 {
129 iptr = ip;
130 calc_fn = fnptr;
131 tag = iptr->getnewtag();
132 iptr->set_cache_entry_validity(tag,false);
133 }
134
135
136template <class T, class S>
137void lazy<T,S>::copy(const lazy &source, const S *ip) {
138 storedval = source.storedval;
139 tag = source.tag;
140 calc_fn = source.calc_fn;
141 // Do NOT copy the same parent class pointer
142 // (allows parent class to be copied correctly)
143 iptr = ip;
144}
145
146 }
147
148#endif
Definition: lazy.h:26
Definition: lazy.h:50