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