Twitch SDK (Internal)
cpp11transition.h
Go to the documentation of this file.
1 /********************************************************************************************
2 * Twitch Broadcasting SDK
3 *
4 * This software is supplied under the terms of a license agreement with Twitch Interactive, Inc. and
5 * may not be copied or used except in accordance with the terms of that agreement
6 * Copyright (c) 2012-2016 Twitch Interactive, Inc.
7 *********************************************************************************************/
8 
9 #pragma once
10 
11 // A few things were accidentally left out of the C++11 standard, but should have been there:
12 // std::make_unique
13 // std::static_pointer_cast for unique_ptrs
14 // std::dynamic_pointer_cast for unique_ptrs
15 // std::const_pointer_cast for unique_ptrs
16 
17 // TODO: This should also have std::allocate_unique
18 
19 #include <type_traits>
20 #include <memory>
21 
22 namespace std
23 {
24  template<typename DesiredType, typename CurrentType>
25  inline unique_ptr<DesiredType> static_pointer_cast(unique_ptr<CurrentType>&& currentPointer)
26  {
27  return unique_ptr<DesiredType>(static_cast<DesiredType*>(currentPointer.release()));
28  }
29 
30  template<typename DesiredType, typename CurrentType>
31  inline unique_ptr<DesiredType> dynamic_pointer_cast(unique_ptr<CurrentType>&& currentPointer)
32  {
33  return unique_ptr<DesiredType>(dynamic_cast<DesiredType*>(currentPointer.release()));
34  }
35 
36  template<typename DesiredType, typename CurrentType>
37  inline unique_ptr<DesiredType> const_pointer_cast(unique_ptr<CurrentType>&& currentPointer)
38  {
39  return unique_ptr<DesiredType>(const_cast<DesiredType*>(currentPointer.release()));
40  }
41 
42 } // namespace std
43 
44 // It is intended to only be used in the preprocessing step, before const variables are considered.
45 
46 
47 #define VC2012 170050727
48 #define VC2012_NOVEMBER_CTP 170051025
49 #define VC2012_UPDATE1 170051106
50 #define VC2012_UPDATE2 170060315
51 
52 #if defined(_MSC_VER)
53  // VC does not support emplace_back until VC2012
54  // (VC10 has an emplace_back, but it only takes one parameter and doesn't actually do in-place construction. So for all intents and purposes, it is useless)
55  #if _MSC_FULL_VER >= VC2012
56  #define TTVSDK_EMPLACE_BACK_SUPPORTED
57 
58  // VC does not support variadic templates until VC2012 Nov CTP
59  // However, VC2012 Update 1 and 2 (which came later) do not support it.
60  // So only doing a greater-than-or-equals on the CTP version number will not work.
61  // I spoke with Stephan T. Lavavej at Microsoft and he said I can do equality to the CTP
62  // and also the next major release of VC.
63  #if _MSC_FULL_VER == VC2012_NOVEMBER_CTP || _MSC_VER >= 1800
64  #define TTVSDK_VARIADIC_TEMPLATES_SUPPORTED
65  #endif
66  #endif
67 #elif defined(__GNUC__)
68  // GCC 4.4+ supports variadic templates
69  #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 4)
70  #define TTVSDK_VARIADIC_TEMPLATES_SUPPORTED
71  #endif
72 #else
73  // Unknown compiler...assume features are not supported
74 #endif
75 
76 #if defined(TTVSDK_VARIADIC_TEMPLATES_SUPPORTED)
77  namespace std
78  {
79 
80  // non-array implementation (as checked by the enable_if)
81  template<typename PointedAtType, typename... ParameterTypes>
82  inline typename std::enable_if<!std::is_array<PointedAtType>::value, std::unique_ptr<PointedAtType>>::type
83  make_unique(ParameterTypes &&... parameters)
84  {
85  return std::unique_ptr<PointedAtType>(new PointedAtType(std::forward<ParameterTypes>(parameters)...));
86  }
87 
88  // array implementation (as checked by the enable_if)
89  template<typename PointedAtType>
90  inline typename std::enable_if<std::is_array<PointedAtType>::value, std::unique_ptr<PointedAtType>>::type
91  make_unique(std::size_t ElementCount)
92  {
93  typedef typename std::remove_extent<PointedAtType>::type ElementType;
94  return std::unique_ptr<PointedAtType>(new ElementType[ElementCount]);
95  }
96 
97  } // namespace std
98 #else // defined TTVSDK_VARIADIC_TEMPLATES_SUPPORTED
99  namespace std
100  {
101 
102  // non-array implementations (as checked by the enable_if)
103  template<typename PointedAtType>
104  inline typename std::enable_if<!std::is_array<PointedAtType>::value, std::unique_ptr<PointedAtType>>::type
106  {
107  return std::unique_ptr<PointedAtType>(new PointedAtType());
108  }
109 
110  template<typename PointedAtType, typename Parameter1Type>
111  inline typename std::enable_if<!std::is_array<PointedAtType>::value, std::unique_ptr<PointedAtType>>::type
112  make_unique(Parameter1Type&& parameter1)
113  {
114  return std::unique_ptr<PointedAtType>(new PointedAtType(std::forward<Parameter1Type>(parameter1)));
115  }
116 
117  template<typename PointedAtType, typename Parameter1Type, typename Parameter2Type>
118  inline typename std::enable_if<!std::is_array<PointedAtType>::value, std::unique_ptr<PointedAtType>>::type
119  make_unique(Parameter1Type&& parameter1, Parameter2Type&& parameter2)
120  {
121  return std::unique_ptr<PointedAtType>(new PointedAtType(std::forward<Parameter1Type>(parameter1), std::forward<Parameter2Type>(parameter2)));
122  }
123 
124  template<typename PointedAtType, typename Parameter1Type, typename Parameter2Type, typename Parameter3Type>
125  inline typename std::enable_if<!std::is_array<PointedAtType>::value, std::unique_ptr<PointedAtType>>::type
126  make_unique(Parameter1Type && parameter1, Parameter2Type && parameter2, Parameter3Type && parameter3)
127  {
128  return std::unique_ptr<PointedAtType>(new PointedAtType(std::forward<Parameter1Type>(parameter1), std::forward<Parameter2Type>(parameter2), std::forward<Parameter3Type>(parameter3)));
129  }
130 
131  template<typename PointedAtType, typename Parameter1Type, typename Parameter2Type, typename Parameter3Type, typename Parameter4Type>
132  inline typename std::enable_if<!std::is_array<PointedAtType>::value, std::unique_ptr<PointedAtType>>::type
133  make_unique(Parameter1Type && parameter1, Parameter2Type && parameter2, Parameter3Type && parameter3, Parameter4Type && parameter4)
134  {
135  return std::unique_ptr<PointedAtType>(new PointedAtType(std::forward<Parameter1Type>(parameter1), std::forward<Parameter2Type>(parameter2), std::forward<Parameter3Type>(parameter3), std::forward<Parameter4Type>(parameter4)));
136  }
137 
138  template<typename PointedAtType, typename Parameter1Type, typename Parameter2Type, typename Parameter3Type, typename Parameter4Type, typename Parameter5Type>
139  inline typename std::enable_if<!std::is_array<PointedAtType>::value, std::unique_ptr<PointedAtType>>::type
140  make_unique(Parameter1Type && parameter1, Parameter2Type && parameter2, Parameter3Type && parameter3, Parameter4Type && parameter4, Parameter5Type && parameter5)
141  {
142  return std::unique_ptr<PointedAtType>(new PointedAtType(std::forward<Parameter1Type>(parameter1), std::forward<Parameter2Type>(parameter2), std::forward<Parameter3Type>(parameter3), std::forward<Parameter4Type>(parameter4), std::forward<Parameter5Type>(parameter5)));
143  }
144 
145  // array implementation (as checked by the enable_if)
146  template<typename PointedAtType>
147  inline typename std::enable_if<std::is_array<PointedAtType>::value, std::unique_ptr<PointedAtType>>::type
148  make_unique(std::size_t ElementCount)
149  {
150  typedef typename std::remove_extent<PointedAtType>::type ElementType;
151  return std::unique_ptr<PointedAtType>(new ElementType[ElementCount]);
152  }
153 
154  } // namespace std
155 #endif // ! defined TTVSDK_VARIADIC_TEMPLATES_SUPPORTED
Definition: cpp11transition.h:22
std::enable_if<!std::is_array< PointedAtType >::value, std::unique_ptr< PointedAtType > >::type make_unique()
Definition: cpp11transition.h:105
unique_ptr< DesiredType > dynamic_pointer_cast(unique_ptr< CurrentType > &&currentPointer)
Definition: cpp11transition.h:31
unique_ptr< DesiredType > const_pointer_cast(unique_ptr< CurrentType > &&currentPointer)
Definition: cpp11transition.h:37
unique_ptr< DesiredType > static_pointer_cast(unique_ptr< CurrentType > &&currentPointer)
Definition: cpp11transition.h:25