1 //todo remove underscores, sanitize module names
2 module glued.annotations.common_annotations;
3 
4 import std.conv: to;
5 
6 import glued.annotations.core_annotations;
7 import glued.annotations.common_impl;
8 
9 private mixin template TargetTypeAnnotationBody() {
10     TargetType[] types;
11     int mask;
12     
13     this(TargetType[] types...){
14         assert(types.length); //todo
15         this.types = types;
16         foreach (TargetType type; types)
17             mask = mask | type;
18     }
19     
20     /**
21      * @param checked - type of element that annotation (annotated with this Target) was put on
22      * @return - if the annotation annotated with Target can be put on checked type of element
23      */
24     bool canAnnotate(TargetType checked){
25         return (mask & to!int(checked)) > 0;
26     }
27 }
28 
29 @OnAnnotation
30 @CheckedBy!(TargetChecker)
31 struct Target {
32     mixin TargetTypeAnnotationBody;
33 }
34 
35 @OnAnnotation
36 @CheckedBy!(TargetOwnerChecker)
37 struct TargetOwner {
38     mixin TargetTypeAnnotationBody;
39 }
40 
41 //todo missing checker, TemplateOf cannot find CODE pieces yet
42 @Target(TargetType.CODE)
43 @TargetOwner(TargetType.TYPE)
44 struct OnStatic {}
45 
46 enum OnAnnotation = Target(TargetType(TargetType.STRUCT));
47 alias Metaannotation = OnAnnotation;
48 
49 struct RepetitionBoundaries {
50     size_t lowerInc;
51     size_t upperExc;
52     
53     invariant {
54         assert(lowerInc >= 0);
55         assert(upperExc > 0);
56         assert(lowerInc < upperExc);
57     }
58     
59     bool check(int occurences){
60         return occurences >= lowerInc && occurences < upperExc;
61     }
62 }
63 
64 RepetitionBoundaries exactly(size_t i){
65     return RepetitionBoundaries(i, i+1);
66 }
67 
68 RepetitionBoundaries atLeast(size_t i){
69     return RepetitionBoundaries(i, size_t.max); //todo infinity?
70 }
71 
72 RepetitionBoundaries atMost(size_t i){
73     return RepetitionBoundaries(0, i+1);
74 }
75 
76 alias between = RepetitionBoundaries;
77 
78 enum exactlyOnce = exactly(1);
79 
80 enum atLeastOnce = atLeast(1);
81 
82 enum atMostOnce = atMost(1);
83 alias optional = atMostOnce;
84 
85 enum notAtAll = RepetitionBoundaries(0, 0);
86 
87 enum anyNumber = RepetitionBoundaries(0, size_t.max);
88 
89 @Metaannotation
90 @CheckedBy!(RepeatableChecker)
91 struct Repeatable {
92     RepetitionBoundaries boundaries = anyNumber;
93 }