UCommon
platform.h
Go to the documentation of this file.
1 // Copyright (C) 2006-2014 David Sugar, Tycho Softworks.
2 // Copyright (C) 2015-2020 Cherokees of Idaho.
3 //
4 // This file is part of GNU uCommon C++.
5 //
6 // GNU uCommon C++ is free software: you can redistribute it and/or modify
7 // it under the terms of the GNU Lesser General Public License as published
8 // by the Free Software Foundation, either version 3 of the License, or
9 // (at your option) any later version.
10 //
11 // GNU uCommon C++ is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU Lesser General Public License for more details.
15 //
16 // You should have received a copy of the GNU Lesser General Public License
17 // along with GNU uCommon C++. If not, see <http://www.gnu.org/licenses/>.
18 
28 #ifdef __clang__
29 #pragma clang diagnostic ignored "-Wpadded"
30 #pragma clang diagnostic ignored "-Wswitch-enum"
31 #pragma clang diagnostic ignored "-Wmissing-noreturn"
32 #pragma clang diagnostic ignored "-Wold-style-cast"
33 #pragma clang diagnostic ignored "-Wcast-qual"
34 #pragma clang diagnostic ignored "-Wzero-as-null-pointer-constant"
35 #endif
36 
37 #ifdef __GNUC__
38 #pragma GCC diagnostic ignored "-Wunused-result"
39 #pragma GCC diagnostic ignored "-Wold-style-cast"
40 #pragma GCC diagnostic ignored "-Wcast-qual"
41 #pragma GCC diagnostic ignored "-Wzero-as-null-pointer-constant"
42 #endif
43 
44 #include <cstdlib>
45 #include <cstddef>
46 #if __cplusplus >= 201103L
47 #include <memory>
48 #endif
49 
50 #if defined(sun) && defined(unix)
51 #include <malloc.h>
52 #endif
53 
54 #ifndef _UCOMMON_PLATFORM_H_
55 #define _UCOMMON_PLATFORM_H_
56 #define UCOMMON_ABI 7
57 
58 #ifndef UCOMMON_SYSRUNTIME
59 #ifndef NEW_STDCPP
60 #define NEW_STDCPP
61 #endif
62 #define _UCOMMON_EXTENDED_
63 #include <stdexcept>
64 #define __THROW_SIZE(x) throw std::length_error(x)
65 #define __THROW_RANGE(x) throw std::out_of_range(x)
66 #define __THROW_RUNTIME(x) throw std::runtime_error(x)
67 #define __THROW_ALLOC() throw std::bad_alloc()
68 #define __THROW_DEREF(v) if(v == nullptr) \
69  throw std::runtime_error("Dereference NULL")
70 #define __THROW_UNDEF(v,x) if(v == nullptr) throw std::runtime_error(x)
71 #else
72 #define __THROW_RANGE(x) abort()
73 #define __THROW_SIZE(x) abort()
74 #define __THROW_RUNTIME(x) abort()
75 #define __THROW_ALLOC() abort()
76 #define __THROW_DEREF(v) if(v == nullptr) abort()
77 #define __THROW_UNDEF(v,x) if(v == nullptr) abort()
78 #endif
79 
90 #define UCOMMON_NAMESPACE ucommon
91 #define NAMESPACE_UCOMMON namespace ucommon {
92 #define END_NAMESPACE }
93 
94 #ifndef _REENTRANT
95 #define _REENTRANT 1
96 #endif
97 
98 #ifndef __PTH__
99 #ifndef _THREADSAFE
100 #define _THREADSAFE 1
101 #endif
102 
103 #ifndef _POSIX_PTHREAD_SEMANTICS
104 #define _POSIX_PTHREAD_SEMANTICS
105 #endif
106 #endif
107 
108 #if !defined(__GNUC__) && !defined(__has_feature) && !defined(_MSC_VER)
109 #define UCOMMON_RTTI 1
110 #endif
111 
112 #if __GNUC__ > 3 && defined(__GXX_RTTI)
113 #define UCOMMON_RTTI 1
114 #endif
115 
116 #if defined(_MSC_VER) && defined(_CPPRTTI)
117 #define UCOMMON_RTTI 1
118 #endif
119 
120 #if defined(__has_feature)
121 #if __has_feature(cxx_rtti)
122 #define UCOMMON_RTTI 1
123 #endif
124 #endif
125 
126 #ifdef UCOMMON_RTTI
127 #define __PROTOCOL virtual
128 template<typename T, typename S>
129 T protocol_cast(S *s) {
130  return dynamic_cast<T>(s);
131 }
132 #else
133 #define __PROTOCOL
134 template<typename T, typename S>
135 T protocol_cast(S *s) {
136  return static_cast<T>(s);
137 }
138 #endif
139 
140 #if defined(__GNUC__) && (__GNUC < 3) && !defined(_GNU_SOURCE)
141 #define _GNU_SOURCE
142 #endif
143 
144 #if !defined(__GNUC_PREREQ__)
145 #if defined(__GNUC__) && defined(__GNUC_MINOR__)
146 #define __GNUC_PREREQ__(maj, min) ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
147 #else
148 #define __GNUC_PREREQ__(maj, min) 0
149 #endif
150 #endif
151 
152 #if __GNUC_PREREQ__(3,3)
153 #define __PRINTF(x,y) __attribute__ ((format (printf, x, y)))
154 #define __SCANF(x, y) __attribute__ ((format (scanf, x, y)))
155 #define __MALLOC __attribute__ ((malloc))
156 #define __NORETURN __attribute__ ((__noreturn__))
157 #endif
158 
159 #define __UNUSED(x) (void)x
160 
161 #if __cplusplus >= 201103L
162 #define __ALIGNED(x) alignas(x)
163 #else
164 #ifdef _MSC_VER
165 #define __ALIGNED(x) __declspec(align(x))
166 #else
167 #define __ALIGNED(x) __attribute__(align(x))
168 #endif
169 #endif
170 
171 #if __cplusplus < 201103L
172 #define __FINAL
173 #define __OVERRIDE
174 #define __DELETED
175 #define __DELETE_COPY(x) inline x(const x&);\
176  inline x& operator=(const x&)
177 #define __DELETE_DEFAULTS(x) inline x();\
178  __DELETE_COPY(x)
179 #else
180 #define __FINAL final
181 #define __OVERRIDE override
182 #define __DELETED =delete
183 #define __DELETE_COPY(x) inline x(const x&) =delete;\
184  inline x& operator=(const x&) =delete
185 #define __DELETE_DEFAULTS(x) inline x() =delete;\
186  __DELETE_COPY(x)
187 #endif
188 
189 #if __cplusplus <= 199711L && !defined(_MSC_VER)
190 #if defined(__GNUC_MINOR__) && !defined(__clang__)
191 #define nullptr __null
192 #elif !defined(__clang__) || (defined(__clang__) && defined(__linux__))
193 const class nullptr_t
194 {
195 public:
196  template<class T>
197  inline operator T*() const {
198  return 0;
199  }
200 
201  template<class C, class T>
202  inline operator T C::*() const {
203  return 0;
204  }
205 
206 private:
207  void operator&() const;
208 
209 } nullptr = {};
210 #endif
211 #endif
212 
213 #ifndef __MALLOC
214 #define __PRINTF(x, y)
215 #define __SCANF(x, y)
216 #define __MALLOC
217 #endif
218 
219 #ifndef DEBUG
220 #ifndef NDEBUG
221 #define NDEBUG
222 #endif
223 #endif
224 
225 #ifdef DEBUG
226 #ifdef NDEBUG
227 #undef NDEBUG
228 #endif
229 #endif
230 
231 // see if targeting legacy Microsoft windows platform
232 
233 #if defined(_MSC_VER) || defined(WIN32) || defined(_WIN32)
234 #define _MSWINDOWS_
235 
236 #if defined(_MSC_VER)
237 #define NOMINMAX
238 #if _MSC_VER < 1500
239 #warning "Probably won't build, need VS >= 2010 or later"
240 #endif
241 #endif
242 
243 // minimum required version requires conditional
244 #ifdef _WIN32_WINNT
245 #if _WIN32_WINNT < 0x0600
246 #undef _WIN32_WINNT
247 #undef WINVER
248 #endif
249 #endif
250 
251 #ifndef _WIN32_WINNT
252 #define _WIN32_WINNT 0x0600
253 #endif
254 
255 #ifdef _MSC_VER
256 #pragma warning(disable: 4251)
257 #pragma warning(disable: 4996)
258 #pragma warning(disable: 4355)
259 #pragma warning(disable: 4290)
260 #pragma warning(disable: 4291)
261 #endif
262 
263 #if defined(__BORLANDC__) && !defined(__MT__)
264 #error Please enable multithreading
265 #endif
266 
267 #if defined(_MSC_VER) && !defined(_MT)
268 #error Please enable multithreading (Project -> Settings -> C/C++ -> Code Generation -> Use Runtime Library)
269 #endif
270 
271 // Make sure we're consistent with _WIN32_WINNT
272 #ifndef WINVER
273 #define WINVER _WIN32_WINNT
274 #endif
275 
276 #ifndef WIN32_LEAN_AND_MEAN
277 #define WIN32_LEAN_AND_MEAN
278 #endif
279 
280 #include <winsock2.h>
281 #include <ws2tcpip.h>
282 
283 #if defined(_MSC_VER)
284 typedef int socksize_t;
285 typedef int socklen_t;
286 typedef signed long ssize_t;
287 typedef int pid_t;
288 #else
289 typedef size_t sockword_t;
290 typedef size_t socksize_t;
291 #endif
292 
293 #include <process.h>
294 #ifndef __EXPORT
295 #ifdef UCOMMON_STATIC
296 #define __EXPORT
297 #else
298 #define __EXPORT __declspec(dllimport)
299 #endif
300 #endif
301 #define __LOCAL
302 
303 // if runtime mode then non-runtime libraries are static on windows...
304 #if defined(UCOMMON_RUNTIME) || defined(UCOMMON_STATIC)
305 #define __SHARED
306 #else
307 #define __SHARED __declspec(dllimport)
308 #endif
309 
310 #else
311 typedef size_t socksize_t;
312 #define __EXPORT __attribute__ ((visibility("default")))
313 #define __LOCAL __attribute__ ((visibility("hidden")))
314 #define __SHARED __attribute__ ((visibility("default")))
315 #endif
316 
317 #ifdef _MSWINDOWS_
318 
319 #define _UWIN
320 
321 #include <sys/stat.h>
322 #include <io.h>
323 
324 // gcc mingw can do native high performance win32 conditionals...
325 #if defined(UCOMMON_WINPTHREAD) && __GNUC_PREREQ__(4, 8) && !defined(UCOMMON_SYSRUNTIME)
326 #define __MINGW_WINPTHREAD__
327 #include <pthread.h> // gnu libstdc++ now requires a win pthread
328 typedef size_t stacksize_t;
329 #else
330 #define _MSTHREADS_
331 typedef DWORD pthread_t;
332 typedef DWORD pthread_key_t;
333 typedef unsigned stacksize_t;
334 typedef CRITICAL_SECTION pthread_mutex_t;
335 #endif
336 typedef char *caddr_t;
337 typedef HANDLE fd_t;
338 typedef SOCKET socket_t;
339 
340 #if defined(_MSC_VER) && defined(_CRT_NO_TIME_T)
341 typedef struct timespec {
342  time_t tv_sec;
343  long tv_nsec;
344 } timespec_t;
345 #endif
346 
347 inline void sleep(int seconds)
348  {::Sleep((seconds * 1000l));}
349 
350 extern "C" {
351 
352  #define __SERVICE(id, argc, argv) void WINAPI service_##id(DWORD argc, LPSTR *argv)
353  #define SERVICE_MAIN(id, argc, argv) void WINAPI service_##id(DWORD argc, LPSTR *argv)
354 
355  typedef LPSERVICE_MAIN_FUNCTION cpr_service_t;
356 
357 #ifdef _MSTHREADS_
358  inline void pthread_exit(void *p)
359  {_endthreadex((DWORD)0);}
360 
361  inline pthread_t pthread_self(void)
362  {return (pthread_t)GetCurrentThreadId();}
363 
364  inline int pthread_mutex_init(pthread_mutex_t *mutex, void *x)
365  {InitializeCriticalSection(mutex); return 0;}
366 
367  inline void pthread_mutex_destroy(pthread_mutex_t *mutex)
368  {DeleteCriticalSection(mutex);}
369 
370  inline void pthread_mutex_lock(pthread_mutex_t *mutex)
371  {EnterCriticalSection(mutex);}
372 
373  inline void pthread_mutex_unlock(pthread_mutex_t *mutex)
374  {LeaveCriticalSection(mutex);}
375 #endif
376 }
377 
378 #elif defined(__PTH__)
379 
380 #include <pth.h>
381 #include <sys/wait.h>
382 
383 typedef size_t stacksize_t;
384 typedef int socket_t;
385 typedef int fd_t;
386 #define INVALID_SOCKET -1
387 #define INVALID_HANDLE_VALUE -1
388 #include <signal.h>
389 
390 #define pthread_mutex_t pth_mutex_t
391 #define pthread_cond_t pth_cond_t
392 #define pthread_t pth_t
393 
394 inline int pthread_sigmask(int how, const sigset_t *set, sigset_t *oset)
395  {return pth_sigmask(how, set, oset);};
396 
397 inline void pthread_exit(void *p)
398  {pth_exit(p);};
399 
400 inline void pthread_kill(pthread_t tid, int sig)
401  {pth_raise(tid, sig);};
402 
403 inline int pthread_mutex_init(pthread_mutex_t *mutex, void *x)
404  {return pth_mutex_init(mutex) != 0;};
405 
406 inline void pthread_mutex_destroy(pthread_mutex_t *mutex)
407  {};
408 
409 inline void pthread_mutex_lock(pthread_mutex_t *mutex)
410  {pth_mutex_acquire(mutex, 0, nullptr);};
411 
412 inline void pthread_mutex_unlock(pthread_mutex_t *mutex)
413  {pth_mutex_release(mutex);};
414 
415 inline void pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
416  {pth_cond_await(cond, mutex, nullptr);};
417 
418 inline void pthread_cond_signal(pthread_cond_t *cond)
419  {pth_cond_notify(cond, FALSE);};
420 
421 inline void pthread_cond_broadcast(pthread_cond_t *cond)
422  {pth_cond_notify(cond, TRUE);};
423 
424 #else
425 
426 #include <pthread.h>
427 
428 typedef size_t stacksize_t;
429 typedef int socket_t;
430 typedef int fd_t;
431 #define INVALID_SOCKET -1
432 #define INVALID_HANDLE_VALUE -1
433 #include <signal.h>
434 
435 #endif
436 
437 #ifdef _MSC_VER
438 typedef signed __int8 int8_t;
439 typedef unsigned __int8 uint8_t;
440 typedef signed __int16 int16_t;
441 typedef unsigned __int16 uint16_t;
442 typedef signed __int32 int32_t;
443 typedef unsigned __int32 uint32_t;
444 typedef signed __int64 int64_t;
445 typedef unsigned __int64 uint64_t;
446 typedef char *caddr_t;
447 
448 #include <stdio.h>
449 #define snprintf(p, s, f, ...) _snprintf_s(p, s, _TRUNCATE, f, __VA_ARGS__)
450 #define vsnprintf(p, s, f, a) _vsnprintf_s(p, s, _TRUNCATE, f, a)
451 
452 #else
453 
454 #include <sys/stat.h>
455 #include <sys/types.h>
456 #include <stdint.h>
457 #include <unistd.h>
458 #include <stdio.h>
459 
460 #endif
461 
462 #undef getchar
463 #undef putchar
464 
465 #ifndef _GNU_SOURCE
466 typedef void (*sighandler_t)(int);
467 #endif
468 typedef unsigned long timeout_t;
469 
470 #include <cctype>
471 #include <climits>
472 #include <cerrno>
473 #ifndef UCOMMON_RUNTIME
474 #include <new>
475 #endif
476 
477 #ifdef _MSWINDOWS_
478 #ifndef ENETDOWN
479 #define ENETDOWN ((int)(WSAENETDOWN))
480 #endif
481 #ifndef EINPROGRESS
482 #define EINPROGRESS ((int)(WSAEINPROGRESS))
483 #endif
484 #ifndef ENOPROTOOPT
485 #define ENOPROTOOPT ((int)(WSAENOPROTOOPT))
486 #endif
487 #ifndef EADDRINUSE
488 #define EADDRINUSE ((int)(WSAEADDRINUSE))
489 #endif
490 #ifndef EADDRNOTAVAIL
491 #define EADDRNOTAVAIL ((int)(WSAEADDRNOTAVAIL))
492 #endif
493 #ifndef ENETUNREACH
494 #define ENETUNREACH ((int)(WSAENETUNREACH))
495 #endif
496 #ifndef EHOSTUNREACH
497 #define EHOSTUNREACH ((int)(WSAEHOSTUNREACH))
498 #endif
499 #ifndef EHOSTDOWN
500 #define EHOSTDOWN ((int)(WSAEHOSTDOWN))
501 #endif
502 #ifndef ENETRESET
503 #define ENETRESET ((int)(WSAENETRESET))
504 #endif
505 #ifndef ECONNABORTED
506 #define ECONNABORTED ((int)(WSAECONNABORTED))
507 #endif
508 #ifndef ECONNRESET
509 #define ECONNRESET ((int)(WSAECONNRESET))
510 #endif
511 #ifndef EISCONN
512 #define EISCONN ((int)(WSAEISCONN))
513 #endif
514 #ifndef ENOTCONN
515 #define ENOTCONN ((int)(WSAENOTCONN))
516 #endif
517 #ifndef ESHUTDOWN
518 #define ESHUTDOWN ((int)(WSAESHUTDOWN))
519 #endif
520 #ifndef ETIMEDOUT
521 #define ETIMEDOUT ((int)(WSAETIMEDOUT))
522 #endif
523 #ifndef ECONNREFUSED
524 #define ECONNREFUSED ((int)(WSAECONNREFUSED))
525 #endif
526 #endif
527 
528 #ifndef DEBUG
529 #ifndef NDEBUG
530 #define NDEBUG
531 #endif
532 #endif
533 
534 #ifdef DEBUG
535 #ifdef NDEBUG
536 #undef NDEBUG
537 #endif
538 #endif
539 
540 #ifndef __PROGRAM
541 #define __PROGRAM(c,v) extern "C" int main(int c, char **v)
542 #define PROGRAM_MAIN(argc, argv) extern "C" int main(int argc, char **argv)
543 #define PROGRAM_EXIT(code) return code
544 #endif
545 
546 #ifndef __SERVICE
547 #define __SERVICE(id, c, v) void service_##id(int c, char **v)
548 #define SERVICE_MAIN(id, argc, argv) void service_##id(int argc, char **argv)
549 typedef void (*cpr_service_t)(int argc, char **argv);
550 #endif
551 
552 #include <assert.h>
553 #ifdef DEBUG
554 #define crit(x, text) assert(x)
555 #else
556 #define crit(x, text) if(!(x)) cpr_runtime_error(text)
557 #endif
558 
565 template<class T>
566 inline T *init(T *memory)
567  {return ((memory) ? new(((void *)memory)) T : nullptr);}
568 
569 typedef long Integer;
570 typedef unsigned long Unsigned;
571 typedef double Real;
572 typedef uint8_t ubyte_t;
573 
578 inline void strfree(char *str)
579  {::free(str);}
580 
581 template<class T, class S>
582 inline T polypointer_cast(S *s)
583 {
584 #if defined(DEBUG) && defined(UCOMMON_RTTI)
585  if(s == nullptr)
586  return nullptr;
587  T ptr = dynamic_cast<T>(s);
588  __THROW_DEREF(ptr);
589  return ptr;
590 #else
591  return static_cast<T>(s);
592 #endif
593 }
594 
595 template<class T, class S>
596 inline T polyconst_cast(S *s)
597 {
598  return const_cast<T>(polypointer_cast<T>(s));
599 }
600 
601 template<class T, class S>
602 inline T polystatic_cast(S *s)
603 {
604  return static_cast<T>(s);
605 }
606 
607 template<class T, class S>
608 inline T polydynamic_cast(S *s)
609 {
610 #if defined(UCOMMON_RTTI)
611  return dynamic_cast<T>(s);
612 #else
613  return static_cast<T>(s);
614 #endif
615 }
616 
617 template<class T, class S>
618 inline T& polyreference_cast(S *s)
619 {
620  __THROW_DEREF(s);
621  return *(static_cast<T*>(s));
622 }
623 
624 template<typename T>
625 inline T& reference_cast(T *pointer) {
626  __THROW_DEREF(pointer);
627  return *pointer;
628 }
629 
630 template<typename T>
631 inline const T immutable_cast(T p)
632 {
633  return static_cast<const T>(p);
634 }
635 
636 #endif
void(* sighandler_t)(int)
Convenient typedef for signal handlers.
Definition: platform.h:466
void strfree(char *str)
Matching function for strdup().
Definition: platform.h:578
T * init(T *memory)
Template function to initialize memory by invoking default constructor.
Definition: platform.h:566
Process services.