1 | // Licensed to the .NET Foundation under one or more agreements. |
2 | // The .NET Foundation licenses this file to you under the MIT license. |
3 | // See the LICENSE file in the project root for more information. |
4 | |
5 | |
6 | |
7 | #pragma once |
8 | |
9 | namespace jitstd |
10 | { |
11 | |
12 | template <typename T> |
13 | inline |
14 | T&& forward(typename jitstd::remove_reference<T>::type& arg) |
15 | { |
16 | return static_cast<T&&>(arg); |
17 | } |
18 | |
19 | template <typename T> |
20 | inline |
21 | T&& forward(typename jitstd::remove_reference<T>::type&& arg) |
22 | { |
23 | static_assert(!jitstd::is_lvalue_reference<T>::value, "unexpected lvalue reference" ); |
24 | return static_cast<T&&>(arg); |
25 | } |
26 | |
27 | namespace utility |
28 | { |
29 | // Template class for scoped execution of a lambda. |
30 | // Usage: |
31 | // |
32 | // auto code = [&] |
33 | // { |
34 | // JITDUMP("finally()"); |
35 | // }; |
36 | // jitstd::utility::scoped_code<decltype(code)> finally(code); |
37 | // "code" will execute when "finally" goes out of scope. |
38 | template <typename T> |
39 | class scoped_code |
40 | { |
41 | public: |
42 | const T& l; |
43 | scoped_code(const T& l) : l(l) { } |
44 | ~scoped_code() { l(); } |
45 | }; |
46 | |
47 | |
48 | // Ensures that "wset" is the union of the initial state of "wset" and "rset". |
49 | // Elements from "rset" that were not in "wset" are added to "cset." |
50 | template <typename Set> |
51 | bool set_union(Set& wset, const Set& rset, Set& cset) |
52 | { |
53 | bool change = false; |
54 | for (typename Set::const_iterator i = rset.begin(); i != rset.end(); ++i) |
55 | { |
56 | jitstd::pair<typename Set::iterator, bool> result = wset.insert(*i); |
57 | if (result.second) |
58 | { |
59 | change = true; |
60 | cset.insert(*i); |
61 | } |
62 | } |
63 | return change; |
64 | } |
65 | |
66 | template <typename Set> |
67 | bool set_union(Set& wset, const Set& rset) |
68 | { |
69 | bool change = false; |
70 | for (typename Set::const_iterator i = rset.begin(); i != rset.end(); ++i) |
71 | { |
72 | jitstd::pair<typename Set::iterator, bool> result = wset.insert(*i); |
73 | change |= result.second; |
74 | } |
75 | return change; |
76 | } |
77 | |
78 | template <typename Set> |
79 | bool set_difference(Set& wset, const Set& rset) |
80 | { |
81 | bool change = false; |
82 | for (typename Set::const_iterator i = rset.begin(); i != rset.end(); ++i) |
83 | { |
84 | if (wset.find(*i) != wset.end()) |
85 | { |
86 | wset.erase(*i); |
87 | change = true; |
88 | } |
89 | } |
90 | |
91 | return change; |
92 | } |
93 | } // end of namespace utility. |
94 | |
95 | } // end of namespace jitstd. |
96 | |