DLG4::VolumeBuilders
A fluent interface for Geant4 geometry definition.
Loading...
Searching...
No Matches
DLG4Units.hh
Go to the documentation of this file.
1// DLG4Units.hh
2// Created by D.S. Leonard on 5/10/26. MIT License
3//
4#ifndef DLG4MODUSIM_DLG4UNITS_HH
5#define DLG4MODUSIM_DLG4UNITS_HH
6#include "G4Types.hh"
7#include "G4ExceptionSeverity.hh" // For FatalException, JustWarning, etc.
8#include "globals.hh" // For G4Exception and G4double
9#include <CLHEP/Units/SystemOfUnits.h>
10#include <G4ThreeVector.hh>
11#include <optional>
12//#include <VolumeBuilderConfigs.hh>
13
14
26// TODO, doxygen all this.
27
28namespace VB = DLG4::VolumeBuilders;
29
30namespace DLG4::Units {
31 template<typename T, class NativeType>
32 class UnitBase;
33 struct UnitTag;
34 class Length;
35 class Mass;
36 class Volume;
37 class Density;
38 class Angle;
39 class Length3Vec;
40 template<typename Dimension>
42
45 class ThreeVecDimensioner;
46
47 template<typename T>
48 inline G4double global_default_unit = 1.0;
49
50
55 template<typename T>
56 inline void SetGlobalDefaultUnit(T unit) {
57 static_assert(std::is_base_of_v<DLG4::Units::UnitTag, T>,
58 "\n\n ERROR: SetGlobalDefaultUnit only accepts DLG4Unit types! \n"
59 " You tried to pass a type that does not inherit from UnitTag.\n");
60 DLG4::Units::global_default_unit<T> = unit.Native;
61 }
62
63 // Set the default value for the global default unit.
64 // (The default for the default for the default).
65 template<>
66 inline G4double global_default_unit<Units::Length> = CLHEP::mm;
67 template<>
68 inline G4double global_default_unit<Units::Mass> = CLHEP::g;
69 template<>
70 inline G4double global_default_unit<Units::Volume> = CLHEP::mL;
71 template<>
72 inline G4double global_default_unit<Units::Length3Vec> = CLHEP::mm;
73 template<>
74 inline G4double global_default_unit<Units::Angle> = CLHEP::radian;
78 template<typename U, typename V>
80 protected:
81 };
82
83 // An inheritance tag for SFINAE
84 struct UnitTag {
85 };
86
91 template<class T, typename NativeType>
92 class UnitBase : public UnitTag {
93 using Derived = T;
94
95 protected:
96 // Raw access to the Native value through a public.
97 // We could convert it to a proxy if needed later.
98 std::optional<NativeType> NativeValue_;
99
100 // Transient temporary calculation handler
101 struct Evaluator {
103 G4double scale;
104
105 // Explicit constructor required for emplace / standard initialization
106 Evaluator(UnitBase &p, G4double s)
107 : parent(p), scale(s) {
108 }
109
110 Evaluator(const Evaluator &) = delete;
111 Evaluator(Evaluator &&) = delete;
112 Evaluator &operator=(const Evaluator &) = delete;
114
115 // Assignment operator
116 // Evaluator is always a temporary rvalue proxy returned by operator(),
117 // but assignment passes through to the permanent parent.
118 // This allows to block auto x = because x is an l-value, and we don't
119 // define l-value assignment!
120 void operator=(NativeType val) && { parent.NativeValue_ = val * scale; }
121 // conversion operator
122 operator NativeType() const {
123 parent.CheckValue("Evaluator");
124 return *(parent.NativeValue_) / scale;
125 }
126
127 friend std::istream &operator>>(std::istream &is, Evaluator &&ev) {
128 NativeType temp_val;
129 if (is >> temp_val) {
130 // Use existing rvalue assignment mechanism to update the parent
131 std::move(ev) = temp_val;
132 }
133 return is;
134 }
135 };
136
137 template<typename X>
139 // A callable proxy, returns a temporary Evaluator that handles both get and set
141
143
144 // delete copy and move ctor to protect the proxy.
145 ScalableProxy(const ScalableProxy &) = delete;
147
148 // Assignment is handled by the temporary Evaluator
150
151 // We return by r-value temporary so we can block the move operator and
152 // prevent auto x = y.InuUnits(...)
153 // But the cost is we need temp storage, and if we have multiple temps in a calculation
154 // we need multiple/separate storage.
155 // An empty token whose only job is to force the C++ compiler to
156 // reserve a dedicated slot on the local stack frame for this exact call.
158 mutable std::optional<Evaluator> storage;
159 };
160
161 // Called on the lvalue member:
162 // This can be const or non-const, but it returns a temporary Evaluator rvalue.
163 // Enables obj.InDefaultUnits = 20.0; // and...
164 // double x = obj.InUnits(cm)
165 Evaluator &&operator()(const X &unit, const ExpressionToken &token = ExpressionToken{}) const {
166 // Initialize the evaluator directly on this call's private stack space
167 token.storage.emplace(parent, unit.Native);
168 unit.CheckUnit("Evaluator");
169 return std::move(*token.storage);
170 }
171 };
172
174 // Non-callable field-like proxy with assignment and conversion operators
175 // Gets a default value for unit conversion
177
179
180 // delete copy and move
183
184 // Enables obj.InDefaultUnits = 20.0;
186 // double x = obj.InDefaultUnits
187 operator NativeType() const { return Evaluator{parent, GetGlobalDefault().NativeValue_.value()}; }
188
189 friend std::istream &operator>>(std::istream &is, DefaultUnitsProxy &proxy) {
190 NativeType temp_val;
191 if (is >> temp_val) {
192 proxy = temp_val; // Reuses your assignment operator above safely
193 }
194 return is;
195 }
196 };
197
198 struct NativeProxy {
199 // Non-callable field-like proxy with assignment and conversion operators
200 // Assigns to or reads the native internal value, no conversion value.
202
204
205 //delete copy and move
206 NativeProxy(const NativeProxy &) = delete;
208
209 // obj.Native = 10.0;
211 // double x = obj.Native
212 operator NativeType() const {
213 parent.CheckValue("NativeProxy");
214 return *(parent.NativeValue_);
215 }
216
217 friend std::istream &operator>>(std::istream &is, NativeProxy &proxy) {
218 NativeType temp_val;
219 if (is >> temp_val) {
220 proxy = temp_val; // Reuses your assignment operator above safely
221 }
222 return is;
223 }
224 };
225
226 public:
230
231 static inline T native{1.0};
232 static T FromNative(NativeType native_value) { return T(native_value); }
233
235 : NativeValue_(std::nullopt) {
236 }
237
238 UnitBase(const UnitBase &other)
239 // Binds the new proxies to the new objects
240 : NativeValue_(other.NativeValue_),
241 InUnits(*this),
242 InDefaultUnits(*this),
243 Native(*this) {
244 }
245
246
247 virtual ~UnitBase() = default;
248
249
250 UnitBase &operator=(const UnitBase &other) {
251 this->NativeValue_ = other.NativeValue_;
252 return *this;
253 }
254
255 explicit UnitBase(double f, Derived u)
256 : NativeValue_(f * u.Native) {u.CheckUnit("UnitBase");}
257
258 static T GetGlobalDefault() { return T(global_default_unit<T>); }
259
260 void CheckValue(const G4String &context) const {
261 // volatile may help with debugging dangling references.
262 volatile bool engagement_flag = NativeValue_.has_value();
263 if (!engagement_flag) {
264 //if (!NativeValue_.has_value()) {
265 G4Exception(context, "InvalidScale", FatalException,
266 "\n Attempted to use a Unit (or measure) before setting it;\n");
267 exit(1);
268 }
269 }
270
271 void CheckUnit(const G4String &context) const {
272 CheckValue(context);
273 if (!(NativeValue_ > 0.0)) {
274 G4Exception(context, "InvalidScale", FatalException,
275 "\n Attempted to apply a negative Unit\n");
276 exit(1);
277 }
278 }
279
280 protected:
281
282 protected:
283 // The public can only make units from existing units, not doubles!!
284 explicit UnitBase(G4double f)
285 : NativeValue_(f) {
286 };
287 };
288
289
290 //#########################################################################//
291 //*********************************Length***************************#
292 //#########################################################################//
293 class Length : public UnitBase<Length, G4double> {
294 friend UnitBase;
295 friend Length3Vec;
296
297 private:
298 explicit Length(double Native)
299 : UnitBase(Native) {
300 }
301
302 public:
303 explicit Length(double raw, Length u)
304 : UnitBase(raw, u) {
305 }
306
308
309 // Declare essentially named singleton factories:
310 static const Length fermi;
311 static const Length angstrom;
312 static const Length nm;
313 static const Length pm;
314 static const Length um;
315 static const Length micron;
316 static const Length mm;
317 static const Length cm;
318 static const Length dm;
319 static const Length m;
320 static const Length km;
321
322 // Imperial
323 static const Length mil;
324 static const Length inch;
325 static const Length foot;
326 static const Length feet;
327 };
328
329 //#########################################################################//
330 // ******************Mass Class
331 //#########################################################################//
332 class Mass : public UnitBase<Mass, G4double> {
334
335 private:
336 explicit Mass(double Native)
337 : UnitBase(Native) {
338 }
339
340 public:
342
343 explicit Mass(double raw, Mass u)
344 : UnitBase(raw, u) {
345 }
346
347 static const Mass g, mg, kg;
348 };
349
350 //#########################################################################//
351 // ******************Volume Class
352 //#########################################################################//
353 class Volume : public UnitBase<Volume, G4double> {
355
356 private:
357 explicit Volume(double Native)
358 : UnitBase(Native) {
359 }
360
361 public:
362 Volume() { NativeValue_ = CLHEP::cm3; };
363
364 explicit Volume(double raw, Volume u)
365 : UnitBase(raw, u) {
366 }
367
368 static const Volume cm3, mL, L;
369 };
370
371
372 //#########################################################################//
373 // ******************Density Class
374 //#########################################################################//
375 class Density : public UnitBase<Density, G4double> {
377
378 private:
379 explicit Density(double Native)
380 : UnitBase(Native) {
381 }
382
383 public:
385
386 explicit Density(double raw, Density u)
387 : UnitBase(raw, u) {
388 }
389
390 static const Density g_per_cm3;
391 static const Density g_per_L; // Same as mg_cm3
392 static const Density mg_per_cm3;
393 };
394
395 //#########################################################################//
396 //*********************************Angle***************************#
397 //#########################################################################//
398 class Angle : public UnitBase<Angle, G4double> {
400
401 private:
402 explicit Angle(double Native)
403 : UnitBase(Native) {
404 }
405
406 public:
408
409 explicit Angle(double raw, Angle u)
410 : UnitBase(raw, u) {
411 }
412
413 static const Angle rad;
414 static const Angle radian;
415 static const Angle mrad;
416 static const Angle milliradian;
417 static const Angle deg;
418 static const Angle degree;
419 };
420
421 inline Density operator/(const Mass &m, const Volume &v) {
423 return x;
424 }
425
426
430 class Length3Vec : public UnitBase<Length3Vec, G4ThreeVector> {
431 // class Length3Vec : public Length {
433 // friend Length;
434 private:
435 //obj.Native.x() doesn't work without casting obj.Native to the vector first.
436 // This proxy wraps the casts to give us direct .Native.x() methods.'
437 struct NativeVectorProxy {
438 Length3Vec &parent;
439
440 void operator=(const G4ThreeVector &val) { parent.NativeValue_ = val; }
441
442 operator G4ThreeVector() const {
443 return static_cast<G4ThreeVector>(static_cast<const UnitBase &>(parent).Native);
444 }
445
446 G4double x() const { return static_cast<G4ThreeVector>(parent.Native).x(); }
447 G4double y() const { return static_cast<G4ThreeVector>(parent.Native).y(); }
448 G4double z() const { return static_cast<G4ThreeVector>(parent.Native).z(); }
449
450 friend std::istream &operator>>(std::istream &is, NativeVectorProxy &proxy) {
451 G4ThreeVector temp_val;
452 if (is >> temp_val) {
453 // Invokes Geant4's native stream parser, then
454 // routes straight into proxy assignment operator
455 proxy = temp_val;
456 }
457 return is;
458 }
459 };
460
461 public:
462 // Shadow the base class member variable
463 NativeVectorProxy Native{*this};
464 // shadow Scalable Proxy to scale with a length, not a vector
465 ScalableProxy<Length> InUnits{*this};
466
468 : Native{*this} {
469 }
470
471 //Copy Constructor
472 Length3Vec(const Length3Vec &other)
473 : UnitBase(other),
474 Native{*this},
475 InUnits{*this},
477 }
478
479 // Move Constructor
480 Length3Vec(Length3Vec &&other) noexcept
481 : UnitBase(std::move(other)),
482 Native{*this},
483 InUnits{*this},
484 default_length_(std::move(other.default_length_)) {
485 }
486
487 // Copy Assignment Operator
489 if (this != &other) {
490 UnitBase::operator=(other); // Safely copies the unified base NativeValue_
491 this->default_length_ = other.default_length_;
492 }
493 return *this;
494 }
495
496 // Move Assignment Operator
497 Length3Vec &operator=(Length3Vec &&other) noexcept {
498 if (this != &other) {
499 UnitBase::operator=(std::move(other)); // Safely moves the unified base NativeValue_
500 this->default_length_ = std::move(other.default_length_);
501 }
502 return *this;
503 }
504
505 Length3Vec(double x, double y, double z, const Length &u) {
506 u.CheckUnit("Length3Vec(x,y,z,u)");
507 NativeValue_ = G4ThreeVector(x, y, z) * u.NativeValue_.value();
508 }
509
510 Length3Vec(const G4ThreeVector &v, const Length &u) {
511 u.CheckUnit("Length3Vec(x,y,z,u)");
512 NativeValue_ = v * u.NativeValue_.value();
513 }
514
515 static Length3Vec FromNative(const G4ThreeVector &v) {
516 return Length3Vec(v, Length::native);
517 }
518
519
520 // components as Length types...
521 Length x() const {
522 CheckValue("Length3Vec");
523 return Length::FromNative(NativeValue_.value().x());
524 }
525
526 Length y() const {
527 CheckValue("Length3Vec");
528 return Length::FromNative(NativeValue_.value().y());
529 }
530
531 Length z() const {
532 CheckValue("Length3Vec");
533 return Length::FromNative(NativeValue_.value().z());
534 }
535
536 void x(const Length &val) {
537 val.CheckValue("Length3Vec, x");
538 EnsureInternalVec().setX(val.NativeValue_.value());
539 }
540
541 void y(const Length &val) {
542 val.CheckValue("Length3Vec, x");
543 EnsureInternalVec().setY(val.NativeValue_.value());
544 }
545
546 void z(const Length &val) {
547 val.CheckValue("Length3Vec, x");
548 EnsureInternalVec().setZ(val.NativeValue_.value());
549 }
550
551 Length3Vec(const Length &x, const Length &y, const Length &z) {
552 x.CheckValue("Length3Vec");
553 y.CheckValue("Length3Vec");
554 z.CheckValue("Length3Vec");
555 NativeValue_ = G4ThreeVector(x.NativeValue_.value(), y.NativeValue_.value(), z.NativeValue_.value());
556 }
557
558 protected:
560
561 private:
562 Length3Vec(G4double value) {
563 }
564
565 // Helper to ensure the optional is initialized before we write to it
566 G4ThreeVector &EnsureInternalVec() {
567 if (!NativeValue_.has_value()) {
568 NativeValue_ = G4ThreeVector(0, 0, 0);
569 }
570 return *NativeValue_;
571 }
572 };
573
574
575 //********************************************************************//
576 // Unit Definitions
577 //********************************************************************//
578
579 // Definitions
580 inline const Length Length::fermi{CLHEP::fermi};
581 inline const Length Length::angstrom{CLHEP::angstrom};
582 inline const Length Length::nm{CLHEP::nanometer};
583 inline const Length Length::pm{1e-9 * CLHEP::mm};
584 inline const Length Length::um{CLHEP::micrometer};
585 inline const Length Length::micron{CLHEP::micrometer}; // Safe alias to um
586 inline const Length Length::mm{CLHEP::mm};
587 inline const Length Length::cm{CLHEP::cm};
588 inline const Length Length::m{CLHEP::m};
589 inline const Length Length::km{CLHEP::kilometer};
590
591 // Imperial Logic: 1 inch = 25.4 mm
592 inline const Length Length::mil{0.0254}; // 1/1000 of an inch
593 inline const Length Length::inch{25.4}; // CLHEP::inch
594 inline const Length Length::foot{304.8}; // 12 inches
595 inline const Length Length::feet{304.8}; // 12 inches
596
597 inline const Mass Mass::mg{CLHEP::mg};
598 inline const Mass Mass::g{CLHEP::g};
599 inline const Mass Mass::kg{CLHEP::kg};
600
601 inline const Volume Volume::mL{CLHEP::mL};
602 inline const Volume Volume::cm3{CLHEP::mL};
603 inline const Volume Volume::L{CLHEP::L};
604
605 inline const Density Density::g_per_cm3{CLHEP::g / CLHEP::cm3};
606 inline const Density Density::g_per_L{CLHEP::g / CLHEP::liter};
607 inline const Density Density::mg_per_cm3{CLHEP::mg / CLHEP::cm3};
608
609 inline const Angle Angle::rad{CLHEP::radian};
610 inline const Angle Angle::radian{CLHEP::radian};
611 inline const Angle Angle::mrad{CLHEP::milliradian};
612 inline const Angle Angle::milliradian{CLHEP::milliradian};
613 inline const Angle Angle::deg{CLHEP::degree};
614 inline const Angle Angle::degree{CLHEP::degree};
615
619 template<class T, class NativeType>
620 struct UnitOrValue {
621 G4double val;
622
624 : val(u.Native) { u.CheckUnit("UnitOrValue"); }
625
626 // Catch any numeric value (int, float, etc.)
627 template<typename Scalar, typename = std::enable_if_t<std::is_arithmetic_v<Scalar> > >
628 UnitOrValue(Scalar d)
629 : val(static_cast<G4double>(d)) {
630 }
631 };
632
633 //********************************************************************//
634 // Math Operators
635 //********************************************************************//
636
637
638 // Multiplication and division of value and unit create Unit.
639 // Which one is the Unit?
640 template<typename T, typename U>
641 using ResultType = std::conditional_t<std::is_base_of_v<UnitTag, T>, T, U>;
642 template<typename T>
643 using NativeType = std::conditional_t<std::is_base_of_v<Length3Vec, T>, G4ThreeVector,
644 std::conditional_t<std::is_base_of_v<UnitTag, T>, G4double,
645 T> >;
646
647 // --- Multiplication: (Unit * value) or (value * Unit) ---
648 template<typename T, typename U,
649 typename = std::enable_if_t<std::is_base_of_v<UnitTag, T> != std::is_base_of_v<UnitTag, U>> >
650 inline auto operator*(const T &a, const U &b) {
651 using R = ResultType<T, U>;
652 return R(UnitOrValue<T, NativeType<T> >(a).val * UnitOrValue<U, NativeType<U> >(b).val, R::native);
653 }
654
655 // --- Division: (Unit / Scalar) ---
656 template<typename T, typename U,
657 typename = std::enable_if_t<std::is_base_of_v<UnitTag, T> && !std::is_base_of_v<UnitTag, U>> >
658 inline auto operator/(const T &a, const U &b) {
659 // T is the Unit, U is the Scalar
660 return T(UnitOrValue<T, NativeType<T> >(a).val / static_cast<double>(b), T::native);
661 }
662
663 // --- Addition: T + T (where T inherits from UnitTag) ---
664 template<typename T, typename = std::enable_if_t<std::is_base_of_v<UnitTag, T> > >
665 inline T operator+(const T &a, const T &b) {
666 // Uses the protected constructor/FromNative to return a new dimensioned object
667 return T::FromNative(a.Native + b.Native);
668 }
669
670 // --- Subtraction: T - T (where T inherits from UnitTag) ---
671 template<typename T, typename = std::enable_if_t<std::is_base_of_v<UnitTag, T> > >
672 inline T operator-(const T &a, const T &b) {
673 return T::FromNative(a.Native - b.Native);
674 }
675
676
677 using UnitlessG4Transform3D = G4Transform3D;
678
679 template<typename T, typename = void>
680 struct is_valid_expr : std::false_type {
681 };
682
683 template<typename T>
684 struct is_valid_expr<T, std::void_t<decltype(std::declval<T>()())> > : std::true_type {
685 };
686
687 // Syntactic sugar variable template
688 template<typename F>
690
691 // Uncomment below for testing:
692 // class Test {
693 // void testmethod(const Length &u) const {
694 // double x = (5.0*Length::mm).Native;
695 // std::stringstream s {"5.0"};
696 // Length in;
697 // s >> in.InUnits(Length::mm);
698 // Length x = 5.0 * Length::mm;
699 // Length y = Length::FromNative(5.0);
700 // auto z = x + y;
701 // static_assert(is_invalid_expression<decltype([&]() {
702 // auto a = z.InDefaultUnits;
703 // })>, "Test Failed: auto deducing a proxy should not compile");
704 // auto a = z.InUnits(Length::mm);
705 // static_assert(is_invalid_expression<decltype([&]() {
706 // auto g = z.InUnits(Length::mm);
707 // })>, "Test Failed: auto deducing a proxy should not compile");
708 //
709 // double a = z.InDefaultUnits;
710 // z.InDefaultUnits = 10;
711 // double b = z.InUnits(Length::mm);
712 // z.InUnits(Length::mm) = 10;
713 // static_assert(is_invalid_expression<decltype([&]() {
714 // auto b = z.InDefaultUnits;
715 // })>, "Test Failed: auto deducing a proxy should not compile");
716 //
717 // static_assert(is_invalid_expression<decltype([&]() {
718 // auto a = z.InDefaultUnits;
719 // })>, "Test Failed: auto deducing a proxy should not compile");
720 //
721 // static_assert(is_invalid_expression<decltype([&]() {
722 // Length x = 5.0;
723 // })>, "Test Failed: Length x = 5.0 should not compile.");
724 //
725 // static_assert(is_invalid_expression<decltype([&]() {
726 // Length x = Length::mm;
727 // x = x * Length::mm; // Actual code block being tested
728 // })>, "Test Failed: x = x * Length::mm should not compile.");
729 //
730 // static_assert(is_invalid_expression<decltype([&]() {
731 // auto result = Length::mm + Mass::g;
732 // })>, "Test Failed: Adding Mass to Length should not compile.");
733 //
734 // static_assert(is_invalid_expression<decltype([&]() {
735 // Length x = Length::mm;
736 // auto c = x + 5.0; // Actual code block being tested
737 // })>, "Test Failed: cannot add Length to double");
738 // }
739 // };
740 class MoreTest {
741 void testmethod() {
742 Length x;
743 x.Native = 5.0;
744 }
745 };
746
747};
748
749#endif //DLG4MODUSIM_DLG4UNITS_HH
static const Angle deg
Definition DLG4Units.hh:417
static const Angle radian
Definition DLG4Units.hh:414
static const Angle rad
Definition DLG4Units.hh:413
static const Angle degree
Definition DLG4Units.hh:418
static const Angle milliradian
Definition DLG4Units.hh:416
static const Angle mrad
Definition DLG4Units.hh:415
Angle(double raw, Angle u)
Definition DLG4Units.hh:409
static const Density g_per_cm3
Definition DLG4Units.hh:390
Density(double raw, Density u)
Definition DLG4Units.hh:386
static const Density mg_per_cm3
Definition DLG4Units.hh:392
static const Density g_per_L
Definition DLG4Units.hh:391
A 3 vector that is scalable with/to Units.
Definition DLG4Units.hh:430
static Length3Vec FromNative(const G4ThreeVector &v)
Definition DLG4Units.hh:515
Length3Vec(const Length &x, const Length &y, const Length &z)
Definition DLG4Units.hh:551
void y(const Length &val)
Definition DLG4Units.hh:541
ScalableProxy< Length > InUnits
Definition DLG4Units.hh:465
Length3Vec(const G4ThreeVector &v, const Length &u)
Definition DLG4Units.hh:510
NativeVectorProxy Native
Definition DLG4Units.hh:463
Length3Vec(Length3Vec &&other) noexcept
Definition DLG4Units.hh:480
void x(const Length &val)
Definition DLG4Units.hh:536
Length3Vec(const Length3Vec &other)
Definition DLG4Units.hh:472
Length3Vec(double x, double y, double z, const Length &u)
Definition DLG4Units.hh:505
void z(const Length &val)
Definition DLG4Units.hh:546
Length3Vec & operator=(Length3Vec &&other) noexcept
Definition DLG4Units.hh:497
Length3Vec & operator=(const Length3Vec &other)
Definition DLG4Units.hh:488
static const Length nm
Definition DLG4Units.hh:312
static const Length feet
Definition DLG4Units.hh:326
static const Length mil
Definition DLG4Units.hh:323
static const Length fermi
Definition DLG4Units.hh:310
Length(double raw, Length u)
Definition DLG4Units.hh:303
static const Length um
Definition DLG4Units.hh:314
static const Length mm
Definition DLG4Units.hh:316
static const Length dm
Definition DLG4Units.hh:318
static const Length m
Definition DLG4Units.hh:319
static const Length angstrom
Definition DLG4Units.hh:311
static const Length foot
Definition DLG4Units.hh:325
static const Length inch
Definition DLG4Units.hh:324
static const Length km
Definition DLG4Units.hh:320
static const Length pm
Definition DLG4Units.hh:313
static const Length micron
Definition DLG4Units.hh:315
static const Length cm
Definition DLG4Units.hh:317
static const Mass mg
Definition DLG4Units.hh:347
static const Mass kg
Definition DLG4Units.hh:347
Mass(double raw, Mass u)
Definition DLG4Units.hh:343
static const Mass g
Definition DLG4Units.hh:347
CRTP base methods for Unit classes.
Definition DLG4Units.hh:92
static T FromNative(NativeType native_value)
Definition DLG4Units.hh:232
void CheckValue(const G4String &context) const
Definition DLG4Units.hh:260
UnitBase & operator=(const UnitBase &other)
Definition DLG4Units.hh:250
UnitBase(const UnitBase &other)
Definition DLG4Units.hh:238
void CheckUnit(const G4String &context) const
Definition DLG4Units.hh:271
virtual ~UnitBase()=default
UnitBase(double f, Derived u)
Definition DLG4Units.hh:255
std::optional< NativeType > NativeValue_
Definition DLG4Units.hh:98
ScalableProxy< T > InUnits
Definition DLG4Units.hh:227
DefaultUnitsProxy InDefaultUnits
Definition DLG4Units.hh:228
static T GetGlobalDefault()
Definition DLG4Units.hh:258
Effectively a property setter for units.
Definition DLG4Units.hh:79
static const Volume L
Definition DLG4Units.hh:368
static const Volume cm3
Definition DLG4Units.hh:368
Volume(double raw, Volume u)
Definition DLG4Units.hh:364
static const Volume mL
Definition DLG4Units.hh:368
void SetGlobalDefaultUnit(T unit)
Set the global default unit.
Definition DLG4Units.hh:56
Typesafe units!! No accidental mixing values and units.
Definition DLG4Units.hh:30
T operator+(const T &a, const T &b)
Definition DLG4Units.hh:665
std::conditional_t< std::is_base_of_v< Length3Vec, T >, G4ThreeVector, std::conditional_t< std::is_base_of_v< UnitTag, T >, G4double, T > > NativeType
Definition DLG4Units.hh:645
G4double global_default_unit
Definition DLG4Units.hh:48
Density operator/(const Mass &m, const Volume &v)
Definition DLG4Units.hh:421
T operator-(const T &a, const T &b)
Definition DLG4Units.hh:672
G4Transform3D UnitlessG4Transform3D
Definition DLG4Units.hh:677
std::conditional_t< std::is_base_of_v< UnitTag, T >, T, U > ResultType
Definition DLG4Units.hh:641
auto operator*(const T &a, const U &b)
Definition DLG4Units.hh:650
constexpr bool is_invalid_expression
Definition DLG4Units.hh:689
DLG4::Units::Density Density
friend std::istream & operator>>(std::istream &is, DefaultUnitsProxy &proxy)
Definition DLG4Units.hh:189
DefaultUnitsProxy(DefaultUnitsProxy &&)=delete
DefaultUnitsProxy(const DefaultUnitsProxy &)=delete
Evaluator(UnitBase &p, G4double s)
Definition DLG4Units.hh:106
Evaluator(Evaluator &&)=delete
Evaluator & operator=(const Evaluator &)=delete
Evaluator(const Evaluator &)=delete
friend std::istream & operator>>(std::istream &is, Evaluator &&ev)
Definition DLG4Units.hh:127
Evaluator & operator=(Evaluator &&)=delete
void operator=(NativeType val) &&
Definition DLG4Units.hh:120
NativeProxy(NativeProxy &&)=delete
void operator=(NativeType val)
Definition DLG4Units.hh:210
friend std::istream & operator>>(std::istream &is, NativeProxy &proxy)
Definition DLG4Units.hh:217
NativeProxy(const NativeProxy &)=delete
ScalableProxy(ScalableProxy &&)=delete
Evaluator && operator()(const X &unit, const ExpressionToken &token=ExpressionToken{}) const
Definition DLG4Units.hh:165
ScalableProxy(const ScalableProxy &)=delete
ScalableProxy & operator=(const ScalableProxy &)=delete
Type-erases unit or value to just a value.
Definition DLG4Units.hh:620
UnitOrValue(const UnitBase< T, NativeType > &u)
Definition DLG4Units.hh:623