1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef COUNTER_H
10 #define COUNTER_H
11 
12 #include <functional> // for std::hash
13 
14 #include "test_macros.h"
15 
16 struct Counter_base { static int gConstructed; };
17 
18 template <typename T>
19 class Counter : public Counter_base
20 {
21 public:
Counter()22     Counter() : data_()                             { ++gConstructed; }
Counter(const T & data)23     Counter(const T &data) : data_(data)            { ++gConstructed; }
Counter(const Counter & rhs)24     Counter(const Counter& rhs) : data_(rhs.data_)  { ++gConstructed; }
25     Counter& operator=(const Counter& rhs)          { data_ = rhs.data_; return *this; }
26 #if TEST_STD_VER >= 11
Counter(Counter && rhs)27     Counter(Counter&& rhs) : data_(std::move(rhs.data_))  { ++gConstructed; }
28     Counter& operator=(Counter&& rhs) { ++gConstructed; data_ = std::move(rhs.data_); return *this; }
29 #endif
~Counter()30     ~Counter() { --gConstructed; }
31 
get()32     const T& get() const {return data_;}
33 
34     bool operator==(const Counter& x) const {return data_ == x.data_;}
35     bool operator< (const Counter& x) const {return data_ <  x.data_;}
36 
37 private:
38     T data_;
39 };
40 
41 int Counter_base::gConstructed = 0;
42 
43 namespace std {
44 
45 template <class T>
46 struct hash<Counter<T> >
47 {
48     typedef Counter<T> argument_type;
49     typedef std::size_t result_type;
50 
51     std::size_t operator()(const Counter<T>& x) const {return std::hash<T>()(x.get());}
52 };
53 }
54 
55 #endif
56