Spicy
meta.h
1 // Copyright (c) 2020-now by the Zeek Project. See LICENSE for details.
2 
3 #pragma once
4 
5 #include <optional>
6 #include <string>
7 #include <unordered_set>
8 #include <utility>
9 #include <vector>
10 
11 #include <hilti/rt/util.h>
12 
13 #include <hilti/ast/location.h>
14 
15 namespace hilti {
16 class Meta;
17 }
18 
19 template<>
20 struct std::hash<hilti::Meta> {
21  size_t operator()(const hilti::Meta& meta) const;
22 };
23 
24 namespace hilti {
25 
30 class Meta {
31 public:
33  using Comments = std::vector<std::string>;
34 
35  Meta(Location location, Comments comments = {}) : _comments(std::move(comments)) {
36  setLocation(std::move(location));
37  }
38 
40  Meta(Comments comments = {}) : _comments(std::move(comments)) {}
41 
42  Meta(const Meta&) = default;
43  Meta(Meta&&) = default;
44 
45  const Comments& comments() const { return _comments; }
46  const Location& location() const {
47  static Location null;
48  return _location ? *_location : null;
49  }
50 
51  void setLocation(Location l) { _location = std::move(l); }
52  void setComments(Comments c) { _comments = std::move(c); }
53 
54  Meta mergeLocation(const Location& l) const { return Meta(location().merge(l), _comments); }
55 
60  explicit operator bool() const { return _location || _comments.size(); }
61 
62  Meta& operator=(const Meta&) = default;
63  Meta& operator=(Meta&&) = default;
64 
65  friend bool operator==(const Meta& a, const Meta& b) {
66  return a._location == b._location && a._comments == b._comments;
67  }
68 
69  friend bool operator!=(const Meta& a, const Meta& b) { return ! (a == b); }
70 
77  static const Meta* get(Meta m) { return &*_cache.emplace(std::move(m)).first; }
78 
79 private:
80  std::optional<Location> _location;
81  Comments _comments;
82 
83  static std::unordered_set<Meta> _cache; // global cache of meta instances
84 };
85 
86 } // namespace hilti
87 
88 inline size_t std::hash<hilti::Meta>::operator()(const hilti::Meta& meta) const {
89  size_t h = 0;
90  for ( const auto& c : meta.comments() )
91  h = hilti::rt::hashCombine(h, std::hash<std::string>()(c));
92 
93  return hilti::rt::hashCombine(h, std::hash<std::optional<hilti::Location>>()(meta.location()));
94 }
Definition: location.h:17
Definition: meta.h:30
static const Meta * get(Meta m)
Definition: meta.h:77
std::vector< std::string > Comments
Definition: meta.h:33
Meta(Comments comments={})
Definition: meta.h:40