blob: b1b806f2a16a2c15605777423d95437662525847 [file] [log] [blame]
Brian Silverman26e4e522015-12-17 01:56:40 -05001/*----------------------------------------------------------------------------*/
2/* Copyright (c) FIRST 2008. All Rights Reserved. */
3/* Open Source Software - may be modified and shared by FRC teams. The code */
4/* must be accompanied by the FIRST BSD license file in $(WIND_BASE)/WPILib. */
5/*----------------------------------------------------------------------------*/
6#pragma once
7
8// MSVC 2013 doesn't allow "= default" on move constructors, but since we are
9// (currently) only actually using the move constructors in non-MSVC situations
10// (ie, wpilibC++Devices), we can just ignore it in MSVC.
11#if !defined(_MSC_VER)
12#define DEFAULT_MOVE_CONSTRUCTOR(ClassName) \
13ClassName(ClassName &&) = default
14#else
15#define DEFAULT_MOVE_CONSTRUCTOR(ClassName)
16#endif
17
18#if (__cplusplus < 201103L)
19 #if !defined(_MSC_VER)
20 #define nullptr NULL
21 #endif
22 #define constexpr const
23#endif
24
25#if defined(_MSC_VER)
26 #define noexcept throw()
27#endif
28
29// [[deprecated(msg)]] is a C++14 feature not supported by MSVC or GCC < 4.9.
30// We provide an equivalent warning implementation for those compilers here.
31#if defined(_MSC_VER)
32 #define DEPRECATED(msg) __declspec(deprecated(msg))
33#elif defined(__GNUC__)
34 #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 8)
35 #define DEPRECATED(msg) [[deprecated(msg)]]
36 #else
37 #define DEPRECATED(msg) __attribute__((deprecated(msg)))
38 #endif
39#elif __cplusplus > 201103L
40 #define DEPRECATED(msg) [[deprecated(msg)]]
41#else
42 #define DEPRECATED(msg) /*nothing*/
43#endif
44
45// Provide std::decay_t when using GCC < 4.9
46#if defined(__GNUC__)
47 #if __GNUC__ == 4 && __GNUC_MINOR__ < 9
48 #include <type_traits>
49 namespace std {
50 template <class T> using decay_t = typename decay<T>::type;
51 }
52 #endif
53#endif
54
55// A struct to use as a deleter when a std::shared_ptr must wrap a raw pointer
56// that is being deleted by someone else.
57template<class T>
58struct
59NullDeleter {
60 void operator()(T *) const noexcept {};
61};
62
63#include <atomic>
64// Use this for determining whether the default move constructor has been
65// called on a containing object. This serves the purpose of allowing us to
66// use the default move constructor of an object for moving all the data around
67// while being able to use this to, for instance, chose not to de-allocate
68// a PWM port in a destructor.
69struct HasBeenMoved {
70 HasBeenMoved(HasBeenMoved&& other) {
71 other.moved = true;
72 moved = false;
73 }
74 HasBeenMoved() = default;
75 std::atomic<bool> moved{false};
76 operator bool() const { return moved; }
77};
78
79// Define make_unique for C++11-only compilers
80#if __cplusplus == 201103L
81#include <cstddef>
82#include <memory>
83#include <type_traits>
84#include <utility>
85namespace std {
86template <class T>
87struct _Unique_if {
88 typedef unique_ptr<T> _Single_object;
89};
90
91template <class T>
92struct _Unique_if<T[]> {
93 typedef unique_ptr<T[]> _Unknown_bound;
94};
95
96template <class T, size_t N>
97struct _Unique_if<T[N]> {
98 typedef void _Known_bound;
99};
100
101template <class T, class... Args>
102typename _Unique_if<T>::_Single_object make_unique(Args &&... args) {
103 return unique_ptr<T>(new T(std::forward<Args>(args)...));
104}
105
106template <class T>
107typename _Unique_if<T>::_Unknown_bound make_unique(size_t n) {
108 typedef typename remove_extent<T>::type U;
109 return unique_ptr<T>(new U[n]());
110}
111
112template <class T, class... Args>
113typename _Unique_if<T>::_Known_bound make_unique(Args &&...) = delete;
114} // namespace std
115#endif