Develop Biology
The language of life
LinearMotif.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 "UnorderedMotif.h"
31
32#if BIO_CPP_VERSION >= 11
33 #include <type_traits>
34#endif
35
36namespace bio {
37namespace chemical {
38
53template < typename CONTENT_TYPE >
55 public Elementary< LinearMotif< CONTENT_TYPE > >,
56 public chemical::Class< LinearMotif< CONTENT_TYPE > >,
57 public UnorderedMotif< CONTENT_TYPE >
58{
59public:
60
64 typedef typename physical::Line Contents;
65
72
75
76
81 {
83 ret.push_back(property::Linear());
84 return ret;
85 }
86
91 :
92 Elementary< LinearMotif< CONTENT_TYPE > >(GetClassProperties()),
93 chemical::Class< LinearMotif< CONTENT_TYPE > >(this),
95 {
96 CtorCommon();
97 }
98
104 explicit LinearMotif(
105 const Contents* contents,
107 )
108 :
109 Elementary< LinearMotif< CONTENT_TYPE > >(GetClassProperties()),
110 chemical::Class< LinearMotif< CONTENT_TYPE > >(this),
112 {
113 CtorCommon();
114 this->m_contents->Import(contents);
115 }
116
123 :
124 Elementary< LinearMotif< CONTENT_TYPE > >(toCopy.GetClassProperties()),
125 chemical::Class< LinearMotif< CONTENT_TYPE > >(this),
127 {
128 CtorCommon();
129 this->m_contents->Import(toCopy.GetAllImplementation());
130 }
131
137 virtual ~LinearMotif()
138 {
139 this->m_contents->Clear();
140 }
141
148
153 {
154 return m_perspective;
155 }
156
161 {
162 return m_perspective;
163 }
164
170 virtual CONTENT_TYPE AddImplementation(CONTENT_TYPE content)
171 {
172 return ChemicalCast< CONTENT_TYPE >(Cast< physical::Line* >(this->m_contents)->LinearAccess(this->m_contents->Add(content)));
173 }
174
189 CONTENT_TYPE toAdd,
190 const Position position = BOTTOM,
191 const StandardDimension optionalPositionArg = 0, //i.e. invalid.
192 const bool transferSubContents = false
193 )
194 {
195 BIO_SANITIZE(toAdd, ,
196 return code::MissingArgument1())
197
198 Code ret = code::Success();
199
200 SmartIterator toReplace(
201 this->m_contents,
202 InvalidIndex());
203
204 //Remove conflicts
205 for (
206 SmartIterator cnt = this->m_contents->End();
207 !cnt.IsAtBeginning();
208 --cnt
209 )
210 {
211 if (cnt.template As< CONTENT_TYPE >()->IsId(toAdd->GetId()))
212 {
213 //Not an error, but potentially worth noting.
215
216 toReplace = cnt;
217 break; //Only find 1 conflict, as no others should exist.
218 }
219 }
220
221 CONTENT_TYPE addition = CloneAndCast< CONTENT_TYPE >(toAdd);
222 BIO_SANITIZE(addition, ,
223 return code::GeneralFailure())
224
225 if (this->m_contents->IsAllocated(toReplace.GetIndex())) //i.e. GetIndex() != 0.
226 {
227 if (transferSubContents)
228 {
229 //NOTE: THIS REMOVES ALL STRUCTURAL COMPONENTS IN toReplace
230 // WHICH ARE NOT EXPLICITLY IN addition
231 //This makes sense but is bound to be a bug at some point...
232
233 CONTENT_TYPE toReplaceCasted = toReplace.template As< CONTENT_TYPE >();
234 //addition->ImportAll(toReplaceCasted); //<- inaccessible, so we replicate the function here.
235
236 Bond* bondBuffer;
237 for (
238 SmartIterator bnd = addition->AsAtom()->GetAllBonds()->End();
239 !bnd.IsAtBeginning();
240 --bnd
241 )
242 {
243 bondBuffer = bnd;
244 if (bondBuffer->IsEmpty())
245 {
246 continue;
247 }
249 bondBuffer->GetBonded(),
251 {
252 continue;
253 }
254 const physical::Wave* otherBond = toReplaceCasted->AsAtom()->GetBonded(toReplaceCasted->AsAtom()->GetBondPosition(bondBuffer->GetId()));
255 Cast< AbstractMotif* >(bondBuffer->GetBonded())->ImportImplementation(otherBond); //actual work
256 }
257 }
258 this->m_contents->Erase(toReplace);
259 }
260
261 switch (position)
262 {
263 case TOP:
264 {
265 this->m_contents->Insert(
266 addition,
267 this->m_contents->GetBeginIndex());
268 break;
269 }
270 case BEFORE:
271 {
272 Index placement = Cast< physical::Line* >(this->m_contents)->SeekToId(optionalPositionArg);
273 if (!placement)
274 {
275 return code::GeneralFailure();
276 }
277 BIO_SANITIZE(Cast< physical::Line* >(this->m_contents)->LinearAccess(placement)->GetPerspective() == addition->GetPerspective(), ,
278 return code::GeneralFailure());
279
280 this->m_contents->Insert(
281 addition,
282 placement
283 );
284 break;
285 }
286 case AFTER:
287 {
288 Index placement = Cast< physical::Line* >(this->m_contents)->SeekToId(optionalPositionArg);
289 if (!placement)
290 {
291 return code::GeneralFailure();
292 }
293 BIO_SANITIZE(Cast< physical::Line* >(this->m_contents)->LinearAccess(placement)->GetPerspective() == addition->GetPerspective(), ,
294 return code::GeneralFailure());
295
296 this->m_contents->Insert(
297 addition,
298 ++placement
299 );
300 break;
301 }
302 case BOTTOM:
303 {
304 this->m_contents->Insert(
305 addition,
306 this->m_contents->GetEndIndex());
307 break;
308 }
309 default:
310 {
311 this->m_contents->Add(addition);
312 break;
313 }
314 } //switch
315
316 return ret;
317 }
318
324 virtual CONTENT_TYPE GetByIdImplementation(
325 StandardDimension id
326 )
327 {
328 Index ret = Cast< physical::Line* >(this->m_contents)->SeekToId(id);
330 return NULL) //level 2 for GetOrCreate.
331
332 return ChemicalCast< CONTENT_TYPE >(Cast< physical::Line* >(this->m_contents)->LinearAccess(ret));
333 }
334
340 virtual const CONTENT_TYPE GetByIdImplementation(
341 StandardDimension id
342 ) const
343 {
344 Index ret = Cast< physical::Line* >(this->m_contents)->SeekToId(id);
346 return NULL) //level 2 for GetOrCreate.
347
348 return ChemicalCast< CONTENT_TYPE >(Cast< physical::Line* >(this->m_contents)->LinearAccess(ret));
349 }
350
351
357 virtual CONTENT_TYPE GetByNameImplementation(
358 Name name
359 )
360 {
361 Index ret = Cast< physical::Line* >(this->m_contents)->SeekToName(name);
363 return NULL) //level 2 for GetOrCreate.
364
365 return ChemicalCast< CONTENT_TYPE >(Cast< physical::Line* >(this->m_contents)->LinearAccess(ret));
366 }
367
373 virtual const CONTENT_TYPE GetByNameImplementation(
374 Name name
375 ) const
376 {
377 Index ret = Cast< physical::Line* >(this->m_contents)->SeekToName(name);
379 return NULL) //level 2 for GetOrCreate.
380
381 return ChemicalCast< CONTENT_TYPE >(Cast< physical::Line* >(this->m_contents)->LinearAccess(ret));
382 }
383
391 virtual CONTENT_TYPE CreateImplementation(
392 StandardDimension id
393 )
394 {
396 return NULL);
397 return this->AddImplementation((this->GetStructuralPerspective()->template GetTypeFromIdAs< CONTENT_TYPE >(id)));
398 }
399
406 virtual CONTENT_TYPE GetOrCreateByIdImplementation(
407 StandardDimension id
408 )
409 {
410 CONTENT_TYPE ret = this->GetByIdImplementation(
411 id
412 );
413 if (ret)
414 {
415 return ret;
416 }
417 return this->CreateImplementation(id);
418 }
419
427 Name name
428 )
429 {
431 return NULL);
432 //We convert to Id in case the Name is not already registered in the desired Perspective.
433 StandardDimension id = this->GetStructuralPerspective()->GetIdFromName(name);
434 CONTENT_TYPE ret = this->GetByIdImplementation(id);
435 if (ret)
436 {
437 return ret;
438 }
439 return this->CreateImplementation(id);
440 }
441
448 virtual bool HasImplementation(const CONTENT_TYPE& content) const
449 {
450 return this->m_contents->Has(content);
451 }
452
459 {
460 BIO_SANITIZE(other, ,
461 return);
462
463 this->m_contents->Import(other->m_contents);
464 }
465
472 virtual Code Attenuate(const physical::Wave* other)
473 {
475 other,
477 {
478 ForEachImplementation(ChemicalCast< ExcitationBase* >(other));
479 return code::Success();
480 }
481
482 Code ret = code::Success();
483 for (
484 SmartIterator cnt = this->m_contents;
485 !cnt.IsAtBeginning();
486 --cnt
487 )
488 {
489 if (cnt.template As< physical::Identifiable< StandardDimension >* >()->Attenuate(other) != code::Success())
490 {
491 ret = code::UnknownError();
492 }
493 }
494 return ret;
495 }
496
502 virtual Code Disattenuate(const physical::Wave* other)
503 {
504 Code ret = code::Success();
505 for (
506 SmartIterator cnt = this->m_contents;
507 !cnt.IsAtBeginning();
508 --cnt
509 )
510 {
512 {
513 ret = code::UnknownError();
514 }
515 }
516 return ret;
517 }
518
519
524 virtual Emission ForEachImplementation(
525 ExcitationBase* excitation
526 )
527 {
528 Emission ret;
529 for (
530 SmartIterator cnt = this->m_contents;
531 !cnt.IsAtBeginning();
532 --cnt
533 )
534 {
535 ByteStream result;
536 excitation->CallDown(
538 &result
539 );
540 ret.push_back(result);
541 }
542 return ret;
543 }
544
550 virtual std::string GetStringFromImplementation(std::string separator = ", ")
551 {
552 std::string ret = "";
553
554 for (
555 SmartIterator cnt(
556 this->m_contents,
557 this->m_contents->GetBeginIndex());
558 !cnt.IsAtEnd();
559 ++cnt
560 )
561 {
562 ret += cnt.template As< physical::Identifiable< StandardDimension >* >()->GetName();
563 if (cnt.GetIndex() != this->m_contents->GetEndIndex() - 1)
564 {
565 ret += separator;
566 }
567 }
568 return ret;
569 }
570
575 virtual void ClearImplementation()
576 {
577 //No need to delete anything, since our Linear wrapper handles that for us.
578 this->m_contents->Clear();
579 }
580
581private:
582
586 void CtorCommon()
587 {
588 #if BIO_CPP_VERSION >= 11
589 BIO_ASSERT(std::is_base_of<Substance, CONTENT_TYPE>::value);
590 #else
591 CONTENT_TYPE ct;
592 BIO_ASSERT(Cast< Substance* >(&ct) != NULL);
593 #endif
594
595 if (this->m_contents)
596 {
597 delete this->m_contents;
598 }
599 this->m_contents = new physical::Line(4);
600 }
601
602};
603} //chemical namespace
604} //bio namespace
#define BIO_ASSERT(cond)
Definition: AssertMacros.h:29
#define BIO_DISAMBIGUATE_OPTIONAL_CLASS_METHODS(ns, caller)
#define BIO_SANITIZE_AT_SAFETY_LEVEL_2(test, success, failure)
#define BIO_SANITIZE(test, success, failure)
virtual SmartIterator End() const
Definition: Container.cpp:302
virtual void Clear()
Definition: Container.cpp:265
virtual Index Insert(const ByteStream content, const Index index)
Definition: Container.cpp:141
virtual bool IsAllocated(const Index index) const
Definition: Container.cpp:107
virtual Index GetBeginIndex() const
Definition: Container.cpp:64
virtual void Import(const Container *other)
Definition: Container.cpp:251
bool Has(const ByteStream content) const
Definition: Container.cpp:232
virtual Index Add(const ByteStream content)
Definition: Container.cpp:129
virtual bool Erase(Index index)
Definition: Container.cpp:237
virtual Index GetEndIndex() const
Definition: Container.cpp:69
Index GetIndex() const
bool IsAtBeginning() const
bool IsAtEnd() const
static Properties GetClassProperties()
virtual Container * GetAllImplementation()
Wave * GetBonded(Valence position)
Definition: Atom.cpp:210
bool IsEmpty() const
Definition: Bond.cpp:89
AtomicNumber GetId() const
Definition: Bond.cpp:69
physical::Wave * GetBonded()
Definition: Bond.cpp:74
physical::Perspective< StandardDimension > * perspective
Definition: Class.h:80
virtual void CallDown(physical::Wave *wave, ByteStream *ret) const
Definition: Excitation.h:109
static Properties GetClassProperties()
Definition: Excitation.h:73
virtual CONTENT_TYPE AddImplementation(CONTENT_TYPE content)
Definition: LinearMotif.h:170
virtual Code Attenuate(const physical::Wave *other)
Definition: LinearMotif.h:472
static LinearMotif< CONTENT_TYPE > Properties GetClassProperties()
Definition: LinearMotif.h:80
physical::Line Contents
Definition: LinearMotif.h:64
const physical::Perspective< StandardDimension > * GetStructuralPerspective() const
Definition: LinearMotif.h:160
virtual CONTENT_TYPE GetByNameImplementation(Name name)
Definition: LinearMotif.h:357
virtual CONTENT_TYPE GetByIdImplementation(StandardDimension id)
Definition: LinearMotif.h:324
virtual void ClearImplementation()
Definition: LinearMotif.h:575
LinearMotif(const LinearMotif< CONTENT_TYPE > &toCopy)
Definition: LinearMotif.h:122
LinearMotif(physical::Perspective< StandardDimension > *perspective=NULL)
Definition: LinearMotif.h:90
virtual bool HasImplementation(const CONTENT_TYPE &content) const
Definition: LinearMotif.h:448
virtual Code InsertImplementation(CONTENT_TYPE toAdd, const Position position=BOTTOM, const StandardDimension optionalPositionArg=0, const bool transferSubContents=false)
Definition: LinearMotif.h:188
virtual std::string GetStringFromImplementation(std::string separator=", ")
Definition: LinearMotif.h:550
virtual void ImportImplementation(const LinearMotif< CONTENT_TYPE > *other)
Definition: LinearMotif.h:458
virtual CONTENT_TYPE GetOrCreateByIdImplementation(StandardDimension id)
Definition: LinearMotif.h:406
virtual CONTENT_TYPE GetOrCreateByNameImplementation(Name name)
Definition: LinearMotif.h:426
virtual const CONTENT_TYPE GetByIdImplementation(StandardDimension id) const
Definition: LinearMotif.h:340
virtual Emission ForEachImplementation(ExcitationBase *excitation)
Definition: LinearMotif.h:524
virtual CONTENT_TYPE CreateImplementation(StandardDimension id)
Definition: LinearMotif.h:391
physical::Perspective< StandardDimension > * GetStructuralPerspective()
Definition: LinearMotif.h:152
BIO_DISAMBIGUATE_REQUIRED_CLASS_METHODS(chemical, LinearMotif< CONTENT_TYPE >) BIO_DISAMBIGUATE_OPTIONAL_CLASS_METHODS(physical
virtual const CONTENT_TYPE GetByNameImplementation(Name name) const
Definition: LinearMotif.h:373
virtual Code Disattenuate(const physical::Wave *other)
Definition: LinearMotif.h:502
physical::Perspective< StandardDimension > * m_perspective
Definition: LinearMotif.h:147
LinearMotif(const Contents *contents, physical::Perspective< StandardDimension > *perspective=NULL)
Definition: LinearMotif.h:104
virtual Wave * AsWave()
Definition: Class.h:99
virtual Id GetIdFromName(Name name)
Definition: Perspective.h:212
virtual Code Attenuate(const Wave *other)
Definition: Wave.cpp:81
virtual Code Disattenuate(const Wave *other)
Definition: Wave.cpp:86
virtual chemical::Atom * AsAtom()
Definition: Wave.h:209
static Properties GetResonanceBetween(ConstWaves waves)
Definition: Wave.cpp:209
Code UnknownError()
Code SuccessfullyReplaced()
Code Success()
Code GeneralFailure()
Code MissingArgument1()
Property Linear()
Definition: Cell.h:31
uint32_t Index
Definition: Types.h:57
const char * Name
Definition: Types.h:46
const Index InvalidIndex()
Definition: Types.cpp:26
uint8_t Properties
Definition: Types.h:58
Position
Definition: Types.h:46
@ AFTER
Definition: Types.h:49
@ BOTTOM
Definition: Types.h:48
@ TOP
Definition: Types.h:47
@ BEFORE
Definition: Types.h:50