123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566 |
- package cc
- const repTpl = `
- {{ $f := .Field }}{{ $r := .Rules }}{{ $typ := inType $f nil }}
- {{ if $r.GetIgnoreEmpty }}
- if ({{ accessor . }}.size() > 0) {
- {{ end }}
- {{ if $r.GetMinItems }}
- {{ if eq $r.GetMinItems $r.GetMaxItems }}
- if ({{ accessor . }}.size() != {{ $r.GetMinItems }}) {
- {{ err . "value must contain exactly " $r.GetMinItems " item(s)" }}
- }
- {{ else if $r.MaxItems }}
- if ({{ accessor . }}.size() < {{ $r.GetMinItems }} || {{ accessor . }}.size() > {{ $r.GetMaxItems }}) {
- {{ err . "value must contain between " $r.GetMinItems " and " $r.GetMaxItems " items, inclusive" }}
- }
- {{ else }}
- if ({{ accessor . }}.size() < {{ $r.GetMinItems }}) {
- {{ err . "value must contain at least " $r.GetMinItems " item(s)" }}
- }
- {{ end }}
- {{ else if $r.MaxItems }}
- if ({{ accessor . }}.size() > {{ $r.GetMaxItems }}) {
- {{ err . "value must contain no more than " $r.GetMaxItems " item(s)" }}
- }
- {{ end }}
- {{ if $r.GetUnique }}
- // Implement comparison for wrapped reference types
- struct cmp {
- bool operator() (const std::reference_wrapper<{{ $typ }}> lhs, const std::reference_wrapper<{{ $typ }}> rhs) const {
- return lhs.get() == rhs.get();
- }
- };
- // Implement hashing for wrapped reference types
- struct hash {
- std::hash<{{ $typ }}> hash_fn;
- bool operator() (const std::reference_wrapper<{{ $typ }}> ref) const {
- return hash_fn(ref.get());
- }
- };
- // Save a set of references to avoid copying overhead
- std::unordered_set<std::reference_wrapper<{{ $typ }}>, hash, cmp> {{ lookup $f "Unique" }};
- {{ end }}
- {{ if or $r.GetUnique (ne (.Elem "" "").Typ "none") }}
- for (int i = 0; i < {{ accessor . }}.size(); i++) {
- const auto& item = {{ accessor . }}.Get(i);
- (void)item;
- {{ if $r.GetUnique }}
- auto p = {{ lookup $f "Unique" }}.emplace(const_cast<{{ $typ }}&>(item));
- if (p.second == false) {
- {{ errIdx . "i" "repeated value must contain unique items" }}
- }
- {{ end }}
- {{ render (.Elem "item" "i") }}
- }
- {{ end }}
- {{ if $r.GetIgnoreEmpty }}
- }
- {{ end }}
- `
|