77+/
88module mir.annotated ;
99
10- import mir.serde: serdeRegister, serdeAnnotation;
10+ import mir.serde: serdeRegister, serdeAnnotation, serdeIsDynamicAlgebraic ;
1111
1212static immutable excMsg = " At least one annotation is required to create an annotated value." ;
1313version (D_Exceptions)
@@ -22,24 +22,51 @@ struct Annotated(T) {
2222 // /
2323 @serdeAnnotation
2424 string [] annotations;
25- static if (is (T == union ) || is (T == struct ))
25+
26+ static if (! (is (T == union ) || is (T == struct )))
27+ private enum _alloc_ = false ;
28+ else
29+ static if (serdeIsDynamicAlgebraic! T)
30+ private enum _alloc_ = true ;
31+ else
32+ {
33+ import mir.algebraic: isVariant;
34+ static if (isVariant! T)
35+ private enum _alloc_ = true ;
36+ else
37+ private enum _alloc_ = false ;
38+ }
39+
40+ static if (_alloc_)
2641 {
2742 // /
28- private T* _value ;
43+ private T* _value_ ;
2944 // /
30- ref inout (T) value () inout @property
45+ ref inout (T) _value () inout @property
3146 {
32- return * _value;
47+ return * _value_;
48+ }
49+
50+ // /
51+ ref T _value (T value) @property
52+ {
53+ if (_value_ is null )
54+ {
55+ _value_ = new T;
56+ import core.lifetime : move;
57+ * _value_ = move(value);
58+ }
59+ return * _value_;
3360 }
3461 }
3562 else
3663 {
3764 // /
38- T value ;
65+ T _value ;
3966 }
4067
4168 // /
42- alias value this ;
69+ alias _value this ;
4370
4471 /+ +
4572 Params:
@@ -56,13 +83,16 @@ struct Annotated(T) {
5683 }
5784 import core.lifetime : forward;
5885 this .annotations = annotations;
59- static if (is (T == union ) || is (T == struct ) )
60- this ._value = new T(forward! args);
86+ static if (_alloc_ )
87+ this ._value_ = new T(forward! args);
6188 else
6289 static if (__traits(compiles, value = args))
63- this .value = args;
90+ this ._value = args;
91+ else
92+ static if (is (T == class ))
93+ this ._value = new T(forward! args);
6494 else
65- this .value = new T(forward! args);
95+ this ._value = T(forward! args);
6696 }
6797}
6898
@@ -80,3 +110,19 @@ unittest
80110 assert (ac.annotations == annotations);
81111 assert (ac.x == 5 );
82112}
113+
114+ // /
115+ unittest
116+ {
117+ import mir.algebraic;
118+ auto annotations = [" annotation" ];
119+ static struct S {double x;}
120+ auto as = Annotated! (Variant ! S)(annotations, 5 );
121+ assert (as.annotations == annotations);
122+ assert (as.x == 5 );
123+
124+ static struct C {double x;}
125+ auto ac = Annotated! (Variant ! S)(annotations, 5 );
126+ assert (ac.annotations == annotations);
127+ assert (ac.x == 5 );
128+ }
0 commit comments