aboutsummaryrefslogtreecommitdiff
path: root/libbutl/builtin.ixx
blob: 0356f8b6ae83302c17d62cfefdd1fda179b118a0 (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
72
73
74
75
76
77
78
// file      : libbutl/builtin.ixx -*- C++ -*-
// license   : MIT; see accompanying LICENSE file

namespace butl
{
  // builtin
  //
  // Implement timed_wait() function templates in terms of their milliseconds
  // specialization.
  //
  template <>
  LIBBUTL_SYMEXPORT optional<std::uint8_t> builtin::
  timed_wait (const std::chrono::milliseconds&);

  template <typename R, typename P>
  inline optional<std::uint8_t> builtin::
  timed_wait (const std::chrono::duration<R, P>& d)
  {
    using namespace std::chrono;
    return timed_wait (duration_cast<milliseconds> (d));
  }

  inline optional<std::uint8_t> builtin::
  try_wait ()
  {
    if (state_ != nullptr)
    {
      std::unique_lock<std::mutex> l (state_->mutex);

      if (!state_->finished)
        return nullopt;
    }

    return result_;
  }

  // builtin_map
  //
  inline const builtin_info* builtin_map::
  find (const std::string& n) const
  {
    auto i (base::find (n));
    return i != end () ? &i->second : nullptr;
  }

  // builtin::async_state
  //
  template <typename F>
  inline builtin::async_state::
  async_state (F f)
      : thread ([f = std::move (f), this] () mutable noexcept
                {
                  f ();

                  {
                    std::unique_lock<std::mutex> l (this->mutex);
                    finished = true;
                  }

                  condv.notify_all ();
                })
  {
  }

  template <typename F>
  inline builtin
  pseudo_builtin (std::uint8_t& r, F f)
  {
    std::unique_ptr<builtin::async_state> s (
      new builtin::async_state (
        [f = std::move (f), &r] () mutable noexcept
        {
          r = f ();
        }));

    return builtin (r, move (s));
  }
}