Spicy
unit-context.h
1 // Copyright (c) 2020-now by the Zeek Project. See LICENSE for details.
2 
3 #pragma once
4 
5 #include <cassert>
6 #include <string>
7 #include <utility>
8 
9 #include <hilti/rt/exception.h>
10 #include <hilti/rt/type-info.h>
11 #include <hilti/rt/types/reference.h>
12 
13 namespace spicy::rt {
14 
19 HILTI_EXCEPTION(ContextMismatch, UsageError)
20 
21 
28 class UnitContext {
29 public:
36  template<typename T>
38  : _object(std::move(obj)), _type_info(ti) {}
45  template<typename Context>
47  if ( ti != _type_info )
48  throw ContextMismatch(hilti::rt::fmt("context mismatch between related units: expected %s, but got %s",
49  _type_info->display,
50  ti->display));
51 
52  return hilti::rt::any_cast<hilti::rt::StrongReference<Context>>(_object);
53  }
54 
55  UnitContext() = delete;
56  UnitContext(const UnitContext&) = default;
57  UnitContext(UnitContext&&) = default;
58 
59  UnitContext& operator=(const UnitContext&) = default;
60  UnitContext& operator=(UnitContext&&) = default;
61 
62  virtual ~UnitContext(); // trigger vtable
63 
64 private:
65  hilti::rt::any _object;
66  const hilti::rt::TypeInfo* _type_info;
67 };
68 
69 namespace detail {
70 
77 template<typename Context>
78 inline UnitContext createContext(Context ctx, const hilti::rt::TypeInfo* ti) {
79  if ( ti->tag == hilti::rt::TypeInfo::Tag::StrongReference )
80  ti = ti->strong_reference->valueType();
81 
82  return UnitContext(std::move(ctx), ti);
83 }
84 
94 template<typename Context>
95 inline void setContext(hilti::rt::StrongReference<Context>& context,
96  const hilti::rt::TypeInfo* /*context_type*/,
97  const hilti::rt::Optional<UnitContext>& new_ctx,
98  const hilti::rt::TypeInfo* ti) {
99  if ( new_ctx )
100  context = new_ctx->as<Context>(ti);
101  else
102  context = nullptr;
103 }
104 
105 } // namespace detail
106 
107 } // namespace spicy::rt
108 
109 namespace hilti::rt::detail::adl {
110 
111 inline std::string to_string(const spicy::rt::UnitContext& /*ctx*/, rt::detail::adl::tag /*unused*/) {
112  return "<unit context>";
113 }
114 
115 } // namespace hilti::rt::detail::adl
Definition: optional.h:33
Definition: reference.h:399
const TypeInfo * valueType() const
Definition: type-info.h:206
Definition: unit-context.h:28
UnitContext(hilti::rt::StrongReference< T > obj, const hilti::rt::TypeInfo *ti)
Definition: unit-context.h:37
hilti::rt::StrongReference< Context > as(const hilti::rt::TypeInfo *ti) const
Definition: unit-context.h:46
std::string fmt(const char *fmt, const Args &... args)
Definition: fmt.h:17
std::string to_string(T &&x)
Definition: extension-points.h:26
Definition: type-info.h:1276
const char * display
Definition: type-info.h:1278
Tag tag
Tag indicating which field of below union is set.
Definition: type-info.h:1336