DebugServer2
Loading...
Searching...
No Matches
Base.h
1//
2// Copyright (c) 2014-present, Facebook, Inc.
3// All rights reserved.
4//
5// This source code is licensed under the University of Illinois/NCSA Open
6// Source License found in the LICENSE file in the root directory of this
7// source tree. An additional grant of patent rights can be found in the
8// PATENTS file in the same directory.
9//
10
11#pragma once
12
13#if defined(_WIN32)
14// clang-format off
15#include <winsock2.h>
16#include <windef.h>
17// clang-format on
18#if !defined(__MINGW32__)
19typedef SSIZE_T ssize_t;
20#endif
21#else
22#include <cstdlib>
23#endif
24#include <iostream>
25#include <type_traits>
26#include <memory>
27#include <utility>
28
29#if defined(__clang__)
30#define COMPILER_CLANG
31#elif defined(__GNUC__)
32#define COMPILER_GCC
33#elif defined(_MSC_VER)
34#define COMPILER_MSVC
35#else
36#error "Compiler not supported."
37#endif
38
39#if defined(__linux__)
40#define OS_LINUX
41#elif defined(_WIN32)
42#define OS_WIN32
43#elif defined(__FreeBSD__)
44#define OS_FREEBSD
45#elif defined(__APPLE__)
46#define OS_DARWIN
47#else
48#error "Target not supported."
49#endif
50
51#if defined(OS_LINUX) || defined(OS_FREEBSD) || defined(OS_DARWIN)
52#define OS_POSIX
53#endif
54
55#if defined(OS_LINUX)
56#if defined(__TIZEN__)
57#define PLATFORM_TIZEN
58#elif defined(__ANDROID__)
59#define PLATFORM_ANDROID
60#endif
61#elif defined(OS_WIN32)
62#if defined(__MINGW32__)
63#define PLATFORM_MINGW
64#endif
65#endif
66
67#if defined(__arm__) || defined(_M_ARM)
68#define ARCH_ARM
69#define BITSIZE_32
70#elif defined(__aarch64__) || defined(_M_ARM64)
71#define ARCH_ARM64
72#define BITSIZE_64
73#elif defined(__i386__) || defined(_M_IX86)
74#define ARCH_X86
75#define BITSIZE_32
76#elif defined(__x86_64__) || defined(_M_AMD64)
77#define ARCH_X86_64
78#define BITSIZE_64
79#elif defined(__riscv)
80#define ARCH_RISCV
81#if __riscv_xlen == 32
82#define BITSIZE_32
83#elif __riscv_xlen == 64
84#define BITSIZE_64
85#elif __riscv_xlen == 128
86#define BITSIZE_128
87#endif
88#else
89#error "Architecture not supported."
90#endif
91
92#if defined(COMPILER_MSVC)
93#define ENDIAN_LITTLE
94#else
95#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
96#define ENDIAN_LITTLE
97#elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
98#define ENDIAN_BIG
99#elif __BYTE_ORDER__ == __ORDER_PDP_ENDIAN__
100#define ENDIAN_MIDDLE
101#else
102#error "Unknown endianness."
103#endif
104#endif
105
106// We use this weird array_sizeof implementation to get the number of elements
107// in an array in two cases we care about:
108// 1) simple static arrays (e.g.: int foo[10]);
109// 2) more complex structures that have a static array member but use an
110// overload of operator[] to access data, and apply some transforms to the
111// index passed. This happens in CPUState functions.
112//
113// array_sizeof is enabled only if the argument is not a pointer (to avoid the
114// classic sizeof(pointer) bug), and if the argument is a POD type (to avoid
115// users doing array_sizeof(my_std_vector) and such. The idea is that if a type
116// overloads operator[] and is a POD, the underlying storage is probably in the
117// structure, and not held as a reference or a pointer.
118template <typename T>
119typename std::enable_if<
120 !std::is_pointer<T>::value && std::is_pod<T>::value,
121 size_t>::type static inline constexpr array_sizeof(T const &array) {
122 return sizeof(array) / (reinterpret_cast<uintptr_t>(&array[1]) -
123 reinterpret_cast<uintptr_t>(&array[0]));
124}
125
126namespace ds2 {
127
128// We don't use C++14 (yet).
129template <typename T, typename... Args>
130std::unique_ptr<T> make_unique(Args &&... args) {
131 return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
132}
133
134// This thing allows classes with protected constructors to call
135// make_protected_unique to construct a unique_ptr cleanly (which calls
136// make_unique internally). Without this, classes with protected constructors
137// cannot be make_unique'd.
138template <typename T> struct make_unique_enabler {
139 struct make_unique_enabler_helper : public T {
140 template <typename... Args>
141 make_unique_enabler_helper(Args... args) : T(std::forward<Args>(args)...) {}
142 };
143
144 template <typename... Args>
145 static std::unique_ptr<T> make_protected_unique(Args... args) {
146 return ds2::make_unique<make_unique_enabler_helper>(
147 std::forward<Args>(args)...);
148 }
149};
150} // namespace ds2
Definition Base.h:138