MPD  0.20.15
Manual.hxx
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2013 Max Kellermann <max.kellermann@gmail.com>
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *
8  * - Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *
11  * - Redistributions in binary form must reproduce the above copyright
12  * notice, this list of conditions and the following disclaimer in the
13  * documentation and/or other materials provided with the
14  * distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
19  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
20  * FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
22  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
25  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
27  * OF THE POSSIBILITY OF SUCH DAMAGE.
28  */
29 
30 #ifndef MPD_MANUAL_HXX
31 #define MPD_MANUAL_HXX
32 
33 #include "Compiler.h"
34 
35 #include <new>
36 #include <utility>
37 
38 #include <assert.h>
39 
40 #if CLANG_OR_GCC_VERSION(4,7)
41 #pragma GCC diagnostic push
42 #pragma GCC diagnostic ignored "-Wstrict-aliasing"
43 #endif
44 
51 template<class T>
52 class Manual {
53  alignas(T)
54  char data[sizeof(T)];
55 
56 #ifndef NDEBUG
57  bool initialized;
58 #endif
59 
60 public:
61 #ifndef NDEBUG
62  Manual():initialized(false) {}
63  ~Manual() {
64  assert(!initialized);
65  }
66 #endif
67 
68  template<typename... Args>
69  void Construct(Args&&... args) {
70  assert(!initialized);
71 
72  void *p = data;
73  new(p) T(std::forward<Args>(args)...);
74 
75 #ifndef NDEBUG
76  initialized = true;
77 #endif
78  }
79 
80  void Destruct() {
81  assert(initialized);
82 
83  T &t = Get();
84  t.T::~T();
85 
86 #ifndef NDEBUG
87  initialized = false;
88 #endif
89  }
90 
91  T &Get() {
92  assert(initialized);
93 
94  void *p = static_cast<void *>(data);
95  return *static_cast<T *>(p);
96  }
97 
98  const T &Get() const {
99  assert(initialized);
100 
101  const void *p = static_cast<const void *>(data);
102  return *static_cast<const T *>(p);
103  }
104 
105  operator T &() {
106  return Get();
107  }
108 
109  operator const T &() const {
110  return Get();
111  }
112 
113  T *operator->() {
114  return &Get();
115  }
116 
117  const T *operator->() const {
118  return &Get();
119  }
120 };
121 
122 #if CLANG_OR_GCC_VERSION(4,7)
123 #pragma GCC diagnostic pop
124 #endif
125 
126 #endif
Manual()
Definition: Manual.hxx:62
T * operator->()
Definition: Manual.hxx:113
T & Get()
Definition: Manual.hxx:91
const T * operator->() const
Definition: Manual.hxx:117
Container for an object that gets constructed and destructed manually.
Definition: Manual.hxx:52
void Destruct()
Definition: Manual.hxx:80
void Construct(Args &&... args)
Definition: Manual.hxx:69
const T & Get() const
Definition: Manual.hxx:98
~Manual()
Definition: Manual.hxx:63