1 //===----------------------------------------------------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is dual licensed under the MIT and the University of Illinois Open
6 // Source Licenses. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #ifndef COUNTER_H
11 #define COUNTER_H
12 
13 #include <functional> // for std::hash
14 
15 #include "test_macros.h"
16 
17 struct Counter_base { static int gConstructed; };
18 
19 template <typename T>
20 class Counter : public Counter_base
21 {
22 public:
Counter()23     Counter() : data_()                             { ++gConstructed; }
Counter(const T & data)24     Counter(const T &data) : data_(data)            { ++gConstructed; }
Counter(const Counter & rhs)25     Counter(const Counter& rhs) : data_(rhs.data_)  { ++gConstructed; }
26     Counter& operator=(const Counter& rhs)          { data_ = rhs.data_; return *this; }
27 #if TEST_STD_VER >= 11
Counter(Counter && rhs)28     Counter(Counter&& rhs) : data_(std::move(rhs.data_))  { ++gConstructed; }
29     Counter& operator=(Counter&& rhs) { ++gConstructed; data_ = std::move(rhs.data_); return *this; }
30 #endif
~Counter()31     ~Counter() { --gConstructed; }
32 
get()33     const T& get() const {return data_;}
34 
35     bool operator==(const Counter& x) const {return data_ == x.data_;}
36     bool operator< (const Counter& x) const {return data_ <  x.data_;}
37 
38 private:
39     T data_;
40 };
41 
42 int Counter_base::gConstructed = 0;
43 
44 namespace std {
45 
46 template <class T>
47 struct hash<Counter<T> >
48 {
49     typedef Counter<T> argument_type;
50     typedef std::size_t result_type;
51 
52     std::size_t operator()(const Counter<T>& x) const {return std::hash<T>()(x.get());}
53 };
54 }
55 
56 #endif
57