summaryrefslogtreecommitdiff
path: root/tiger-compiler/lib/misc/ref.hxx
blob: ae740fdac4af65f361d9f8a71e1dfee9edb414d9 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
/**
 ** \file misc/ref.hxx
 ** \brief Implementation of misc::ref.
 **/

#pragma once

#include <typeinfo>

#include <misc/ref.hh>

namespace misc
{
  /*-----------------.
  | Ctors and dtor.  |
  `-----------------*/

  template <typename T>
  template <typename U>
  ref<T>::ref(const ref<U>& other)
    : super_type(other)
  {}

  template <typename T>
  ref<T>::ref(const ref<T>& other)
    : super_type(other)
  {}

  template <typename T>
  ref<T>::ref(T* p)
    : super_type(p)
  {}

  /*---------------------.
  | Equality operators.  |
  `---------------------*/

  template <typename T> bool ref<T>::operator==(const T* other) const
  {
    return this->get() == other;
  }

  template <typename T> bool ref<T>::operator!=(const T* other) const
  {
    return !(*this == other);
  }

  /*--------.
  | Casts.  |
  `--------*/

  template <typename T> template <typename U> ref<U> ref<T>::unsafe_cast() const
  {
    ref<U> res;
    (std::dynamic_pointer_cast<U, element_type>(*this)).swap(res);
    return res;
  }

  template <typename T> template <typename U> ref<U> ref<T>::cast() const
  {
    if (!this->get() || !this->is_a<U>())
      throw std::bad_cast();
    return unsafe_cast<U>();
  }

  template <typename T> template <typename U> bool ref<T>::is_a() const
  {
    return dynamic_cast<U*>(this->get());
  }

} // namespace misc