libbio
Loading...
Searching...
No Matches
Metallic.h
Go to the documentation of this file.
1/*
2 * This file is a part of the Biology project by eons LLC.
3 * Biology (aka Develop Biology) is a framework for approaching software
4 * development from a natural sciences perspective.
5 *
6 * Copyright (C) 2022 Séon O'Shannon & eons LLC
7 *
8 * This program is free software: you can redistribute it and/or modify
9 * it under the terms of the GNU Affero General Public License as
10 * published by the Free Software Foundation, either version 3 of the
11 * License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Affero General Public License for more details.
17 *
18 * You should have received a copy of the GNU Affero General Public License
19 * along with this program. If not, see <https://www.gnu.org/licenses/>.
20 */
21
22#pragma once
23
24#include "Atom.h"
25#include "Bond.h"
29
30#include <cstddef>
31#include <vector>
32
33namespace bio {
34//not chemical.
35
50template < class T >
51class Metallic :
52 virtual public chemical::Atom
53{
54public:
59 //@formatter:off
61 mT(::bio::pointer_arena::New< T >())
62 #else
63 mT(new T())
64 #endif
65 //@formatter:on
66 {
67 DonateBonds(mT, this);
68 DonateBonds(this, mT);
69 }
70
75 mT(NULL)
76 {
77 if (other.mT)
78 {
79 //@formatter:off
80 #if BIO_COMPACT_POINTER_STORAGE
81 mT = ::bio::pointer_arena::NewCopy< T >(*other.mT);
82 #else
83 mT = new T(*other.mT);
84 #endif
85 //@formatter:on
86 DonateBonds(mT, this);
87 DonateBonds(this, mT);
88 }
89 }
90
94 virtual ~Metallic()
95 {
96 if (mT)
97 {
100 //@formatter:off
101 #if BIO_COMPACT_POINTER_STORAGE
103 #else
104 delete mT;
105 #endif
106 //@formatter:on
107 mT = NULL;
108 }
109 }
110
115 {
116 if (this == &other)
117 {
118 return *this;
119 }
120 if (mT)
121 {
122 BreakDonatedBonds(this);
124 //@formatter:off
125 #if BIO_COMPACT_POINTER_STORAGE
127 #else
128 delete mT;
129 #endif
130 //@formatter:on
131 mT = NULL;
132 }
133 if (other.mT)
134 {
135 //@formatter:off
136 #if BIO_COMPACT_POINTER_STORAGE
137 mT = ::bio::pointer_arena::NewCopy< T >(*other.mT);
138 #else
139 mT = new T(*other.mT);
140 #endif
141 //@formatter:on
142 DonateBonds(mT, this);
143 DonateBonds(this, mT);
144 }
145 return *this;
146 }
147
152 {
153 return mT;
154 }
155
160 {
161 return mT;
162 }
163
180
182 {
183 std::vector< BondIdentity > entries;
184 };
185
186 static void DonateCollectVisitor(const chemical::Bond& bond, void* ctx)
187 {
188 DonateCollect* collect = static_cast< DonateCollect* >(ctx);
189 // const Bond& -> non-const GetBonded(): the original (pre-RFC-§5)
190 // donor walk operated on a non-const Bond*, and downstream we
191 // hand the bonded Wave* to FormBondImplementation which wants
192 // non-const. ForEachBond hands us const Bond& to advertise
193 // "read-only metadata"; the GetBonded() pointer escape is the
194 // caller's responsibility (RFC §6).
195 Pointer< physical::Wave > bonded = const_cast< chemical::Bond& >(bond).GetBonded();
196 collect->entries.push_back(BondIdentity(bond.GetId(), bonded));
197 }
198
205 static void DonateBonds(
208 )
209 {
210 // Snapshot under donor's shared lock, then mutate receiver without
211 // nesting locks. RFC §5 step 3.
213 donor->ForEachBond(&DonateCollectVisitor, &collect);
214
215 for (std::size_t i = 0; i < collect.entries.size(); ++i)
216 {
217 const BondIdentity& entry = collect.entries[i];
218
219 //Skip already Bonded objects.
220 if (receiver->GetBondPosition(entry.id))
221 {
222 continue;
223 }
224
225 //Nuke the BondType, since it could lead to deleting the same pointer twice.
226 //We also want to keep track of where the Bonds came from.
227 receiver->FormBondImplementation(
228 entry.bonded,
229 entry.id,
231 );
232 }
233 }
234
236 {
238 std::vector< chemical::AtomicNumber > ids;
239 };
240
242 {
244 if (bond.GetType() != collect->expectedType)
245 {
246 return;
247 }
248 collect->ids.push_back(bond.GetId());
249 }
250
256 {
257 // Snapshot under receiver's shared lock, then break without
258 // nesting receiver's exclusive lock inside the visitor.
259 // RFC §5 step 3.
261 collect.expectedType = GetBondType();
263
264 for (std::size_t i = 0; i < collect.ids.size(); ++i)
265 {
266 const chemical::AtomicNumber id = collect.ids[i];
267 if (!receiver->GetBondPosition(id))
268 {
269 continue;
270 }
271 receiver->BreakBondImplementation(id, GetBondType());
272 }
273 }
274
279 {
280 static const BondType bondId = BondTypePerspective::Instance().GetIdFromName(type::TypeName< Metallic< T > >());
282 return bondId;
283 }
284
285protected:
287};
288
289} //bio namespace
#define BIO_COMPACT_POINTER_STORAGE
Definition OptimizeMacros.h:87
Definition Metallic.h:53
static void DonateCollectVisitor(const chemical::Bond &bond, void *ctx)
Definition Metallic.h:186
virtual ~Metallic()
Definition Metallic.h:94
Metallic()
Definition Metallic.h:58
Metallic & operator=(const Metallic &other)
Definition Metallic.h:114
static void DonateBonds(Pointer< chemical::Atom > donor, Pointer< chemical::Atom > receiver)
Definition Metallic.h:205
Pointer< T > mT
Definition Metallic.h:286
Metallic(const Metallic &other)
Definition Metallic.h:74
static BondType GetBondType()
Definition Metallic.h:278
Pointer< const T > Object() const
Definition Metallic.h:159
static void BreakDonatedBonds(Pointer< chemical::Atom > receiver)
Definition Metallic.h:255
static void BreakDonatedCollectVisitor(const chemical::Bond &bond, void *ctx)
Definition Metallic.h:241
Pointer< T > Object()
Definition Metallic.h:151
Definition Pointer.h:115
T * Get() const
Definition Pointer.h:271
Definition Atom.h:154
Pointer< physical::Wave > GetBonded(Valence position)
Definition Atom.cpp:751
Definition Bond.h:46
void RegisterMetallicBondType(BondType type)
Definition Helpers.cpp:198
void Delete(T *raw)
Definition PointerArena.h:525
BIO_CONSTEXPR ImmutableString TypeName()
Definition FinalCell.h:29
Definition Metallic.h:174
BondIdentity(chemical::AtomicNumber i, Pointer< physical::Wave > b)
Definition Metallic.h:178
chemical::AtomicNumber id
Definition Metallic.h:175
Pointer< physical::Wave > bonded
Definition Metallic.h:176
BondIdentity()
Definition Metallic.h:177
Definition Metallic.h:236
std::vector< chemical::AtomicNumber > ids
Definition Metallic.h:238
BondType expectedType
Definition Metallic.h:237
Definition Metallic.h:182
std::vector< BondIdentity > entries
Definition Metallic.h:183