Line data Source code
1 : /*
2 : * Copyright (c) 2013-2015: G-CSC, Goethe University Frankfurt
3 : * Author: Andreas Vogel
4 : *
5 : * This file is part of UG4.
6 : *
7 : * UG4 is free software: you can redistribute it and/or modify it under the
8 : * terms of the GNU Lesser General Public License version 3 (as published by the
9 : * Free Software Foundation) with the following additional attribution
10 : * requirements (according to LGPL/GPL v3 §7):
11 : *
12 : * (1) The following notice must be displayed in the Appropriate Legal Notices
13 : * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
14 : *
15 : * (2) The following notice must be displayed at a prominent place in the
16 : * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
17 : *
18 : * (3) The following bibliography is recommended for citation and must be
19 : * preserved in all covered files:
20 : * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
21 : * parallel geometric multigrid solver on hierarchically distributed grids.
22 : * Computing and visualization in science 16, 4 (2013), 151-164"
23 : * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
24 : * flexible software system for simulating pde based models on high performance
25 : * computers. Computing and visualization in science 16, 4 (2013), 165-179"
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 :
33 : #ifndef __H__UG__LIB_DISC__COMMON__REVISION_COUNTER__
34 : #define __H__UG__LIB_DISC__COMMON__REVISION_COUNTER__
35 :
36 : #include "common/common.h"
37 :
38 : namespace ug{
39 :
40 : /// Class used to identify a state of adaption of a grid, approx-space, ...
41 : /**
42 : * This class is used as a state counter of an object. E.g., this is very
43 : * useful to track the state of an adaptive multigrid. Based on this counter
44 : * reinitialization of dependent structures can be triggered, that should only
45 : * be reinitialized when actually used again (and not on every state change
46 : * - use observers or msg listeners in that case).
47 : *
48 : * NOTE: the current implementation allows only std::numeric_limits<unit64>::max()
49 : * states (approx 10^20 states), which should be pretty enough for most
50 : * considered uses. If this is not enough a different implementation,
51 : * handling counter overflow, should be used.
52 : * (However, if the state is altered every nano-second, the overflow will
53 : * appear after more than 3000 years)
54 : */
55 : class RevisionCounter
56 : {
57 : public:
58 : /// constructor (with invalid state initialization)
59 0 : RevisionCounter() : m_pObj(0), m_cnt(0) {};
60 :
61 : /// constructor (with valid state initialization)
62 : RevisionCounter(const void* pObj) : m_pObj(pObj), m_cnt(1) {}
63 :
64 : /// constructor (with valid state initialization)
65 : template <typename T>
66 : RevisionCounter(const T* pObj) : m_pObj(static_cast<const void*>(pObj)), m_cnt(1) {}
67 :
68 : /// increase state (prefix)
69 0 : RevisionCounter& operator++() {
70 : if(invalid())
71 0 : UG_THROW("AdaptState: increasing invalid state not admissible.")
72 :
73 0 : ++m_cnt;
74 :
75 : if(invalid())
76 0 : UG_THROW("AdaptState: counter overflow. Alter implementation.")
77 0 : return *this;
78 : }
79 :
80 : /// increase state (postfix)
81 : RevisionCounter operator++(int) {
82 : RevisionCounter tmp(*this);
83 : ++(*this);
84 : return tmp;
85 : }
86 :
87 : /// compare two states
88 : bool operator==(const RevisionCounter& rhs) const{
89 : if(invalid() || rhs.invalid()) return false;
90 0 : if(m_pObj != rhs.m_pObj) return false;
91 0 : return (m_cnt == rhs.m_cnt);
92 : }
93 :
94 : /// compare two states
95 : bool operator!=(const RevisionCounter& rhs) const{
96 : return !((*this) == rhs);
97 : }
98 :
99 : /// compare two states
100 : bool operator<(const RevisionCounter& rhs) const{
101 0 : if(m_pObj != rhs.m_pObj) return m_pObj < rhs.m_pObj;
102 0 : if(m_cnt != rhs.m_cnt) return m_cnt < rhs.m_cnt;
103 : return false;
104 : }
105 :
106 : /// compare two states
107 : bool operator>(const RevisionCounter& rhs) const{
108 : if(m_pObj != rhs.m_pObj) return m_pObj > rhs.m_pObj;
109 : if(m_cnt != rhs.m_cnt) return m_cnt > rhs.m_cnt;
110 : return false;
111 : }
112 :
113 : /// returns if state is valid
114 0 : bool valid() const {return m_pObj != 0 && m_cnt != 0;}
115 :
116 : /// returns if state is invalid
117 : bool invalid() const {return !valid();}
118 :
119 : /// invalidates state
120 0 : void invalidate() {m_pObj = 0; m_cnt = 0;}
121 :
122 : /// returns the associated object
123 0 : const void* obj() const {return m_pObj;}
124 :
125 : protected:
126 : const void* m_pObj; ///< associated object
127 : uint64 m_cnt; ///< state counter (0 = invalid)
128 : };
129 :
130 : } // end namespace ug
131 :
132 : #endif /* __H__UG__LIB_DISC__COMMON__REVISION_COUNTER__ */
|