From c5fc66ee58f2c60f2d226868bb1cf5b91badaf53 Mon Sep 17 00:00:00 2001 From: sanine Date: Sat, 1 Oct 2022 20:59:36 -0500 Subject: add ode --- libs/ode-0.16.1/ou/include/ou/Makefile.am | 17 + libs/ode-0.16.1/ou/include/ou/Makefile.in | 457 +++++ libs/ode-0.16.1/ou/include/ou/assert.h | 188 ++ libs/ode-0.16.1/ou/include/ou/atomic.h | 1835 ++++++++++++++++++++ libs/ode-0.16.1/ou/include/ou/atomicflags.h | 367 ++++ libs/ode-0.16.1/ou/include/ou/customization.h | 149 ++ libs/ode-0.16.1/ou/include/ou/enumarrays.h | 256 +++ libs/ode-0.16.1/ou/include/ou/features.h | 51 + libs/ode-0.16.1/ou/include/ou/flags.h | 35 + libs/ode-0.16.1/ou/include/ou/flagsdefines.h | 37 + libs/ode-0.16.1/ou/include/ou/inttypes.h | 136 ++ libs/ode-0.16.1/ou/include/ou/macros.h | 79 + libs/ode-0.16.1/ou/include/ou/malloc.h | 48 + libs/ode-0.16.1/ou/include/ou/namespace.h | 43 + libs/ode-0.16.1/ou/include/ou/platform.h | 398 +++++ libs/ode-0.16.1/ou/include/ou/simpleflags.h | 334 ++++ libs/ode-0.16.1/ou/include/ou/templates.h | 90 + libs/ode-0.16.1/ou/include/ou/threadlocalstorage.h | 297 ++++ libs/ode-0.16.1/ou/include/ou/typewrapper.h | 111 ++ 19 files changed, 4928 insertions(+) create mode 100644 libs/ode-0.16.1/ou/include/ou/Makefile.am create mode 100644 libs/ode-0.16.1/ou/include/ou/Makefile.in create mode 100644 libs/ode-0.16.1/ou/include/ou/assert.h create mode 100644 libs/ode-0.16.1/ou/include/ou/atomic.h create mode 100644 libs/ode-0.16.1/ou/include/ou/atomicflags.h create mode 100644 libs/ode-0.16.1/ou/include/ou/customization.h create mode 100644 libs/ode-0.16.1/ou/include/ou/enumarrays.h create mode 100644 libs/ode-0.16.1/ou/include/ou/features.h create mode 100644 libs/ode-0.16.1/ou/include/ou/flags.h create mode 100644 libs/ode-0.16.1/ou/include/ou/flagsdefines.h create mode 100644 libs/ode-0.16.1/ou/include/ou/inttypes.h create mode 100644 libs/ode-0.16.1/ou/include/ou/macros.h create mode 100644 libs/ode-0.16.1/ou/include/ou/malloc.h create mode 100644 libs/ode-0.16.1/ou/include/ou/namespace.h create mode 100644 libs/ode-0.16.1/ou/include/ou/platform.h create mode 100644 libs/ode-0.16.1/ou/include/ou/simpleflags.h create mode 100644 libs/ode-0.16.1/ou/include/ou/templates.h create mode 100644 libs/ode-0.16.1/ou/include/ou/threadlocalstorage.h create mode 100644 libs/ode-0.16.1/ou/include/ou/typewrapper.h (limited to 'libs/ode-0.16.1/ou/include') diff --git a/libs/ode-0.16.1/ou/include/ou/Makefile.am b/libs/ode-0.16.1/ou/include/ou/Makefile.am new file mode 100644 index 0000000..fce65c5 --- /dev/null +++ b/libs/ode-0.16.1/ou/include/ou/Makefile.am @@ -0,0 +1,17 @@ +EXTRA_DIST = assert.h \ + atomicflags.h \ + atomic.h \ + customization.h \ + enumarrays.h \ + features.h \ + flagsdefines.h \ + flags.h \ + inttypes.h \ + macros.h \ + malloc.h \ + namespace.h \ + platform.h \ + simpleflags.h \ + templates.h \ + threadlocalstorage.h \ + typewrapper.h diff --git a/libs/ode-0.16.1/ou/include/ou/Makefile.in b/libs/ode-0.16.1/ou/include/ou/Makefile.in new file mode 100644 index 0000000..bd481ec --- /dev/null +++ b/libs/ode-0.16.1/ou/include/ou/Makefile.in @@ -0,0 +1,457 @@ +# Makefile.in generated by automake 1.15 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994-2014 Free Software Foundation, Inc. + +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ +VPATH = @srcdir@ +am__is_gnu_make = { \ + if test -z '$(MAKELEVEL)'; then \ + false; \ + elif test -n '$(MAKE_HOST)'; then \ + true; \ + elif test -n '$(MAKE_VERSION)' && test -n '$(CURDIR)'; then \ + true; \ + else \ + false; \ + fi; \ +} +am__make_running_with_option = \ + case $${target_option-} in \ + ?) ;; \ + *) echo "am__make_running_with_option: internal error: invalid" \ + "target option '$${target_option-}' specified" >&2; \ + exit 1;; \ + esac; \ + has_opt=no; \ + sane_makeflags=$$MAKEFLAGS; \ + if $(am__is_gnu_make); then \ + sane_makeflags=$$MFLAGS; \ + else \ + case $$MAKEFLAGS in \ + *\\[\ \ ]*) \ + bs=\\; \ + sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \ + | sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \ + esac; \ + fi; \ + skip_next=no; \ + strip_trailopt () \ + { \ + flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \ + }; \ + for flg in $$sane_makeflags; do \ + test $$skip_next = yes && { skip_next=no; continue; }; \ + case $$flg in \ + *=*|--*) continue;; \ + -*I) strip_trailopt 'I'; skip_next=yes;; \ + -*I?*) strip_trailopt 'I';; \ + -*O) strip_trailopt 'O'; skip_next=yes;; \ + -*O?*) strip_trailopt 'O';; \ + -*l) strip_trailopt 'l'; skip_next=yes;; \ + -*l?*) strip_trailopt 'l';; \ + -[dEDm]) skip_next=yes;; \ + -[JT]) skip_next=yes;; \ + esac; \ + case $$flg in \ + *$$target_option*) has_opt=yes; break;; \ + esac; \ + done; \ + test $$has_opt = yes +am__make_dryrun = (target_option=n; $(am__make_running_with_option)) +am__make_keepgoing = (target_option=k; $(am__make_running_with_option)) +pkgdatadir = $(datadir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkglibexecdir = $(libexecdir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +subdir = include/ou +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +DIST_COMMON = $(srcdir)/Makefile.am $(am__DIST_COMMON) +mkinstalldirs = $(install_sh) -d +CONFIG_CLEAN_FILES = +CONFIG_CLEAN_VPATH_FILES = +AM_V_P = $(am__v_P_@AM_V@) +am__v_P_ = $(am__v_P_@AM_DEFAULT_V@) +am__v_P_0 = false +am__v_P_1 = : +AM_V_GEN = $(am__v_GEN_@AM_V@) +am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@) +am__v_GEN_0 = @echo " GEN " $@; +am__v_GEN_1 = +AM_V_at = $(am__v_at_@AM_V@) +am__v_at_ = $(am__v_at_@AM_DEFAULT_V@) +am__v_at_0 = @ +am__v_at_1 = +SOURCES = +DIST_SOURCES = +am__can_run_installinfo = \ + case $$AM_UPDATE_INFO_DIR in \ + n|no|NO) false;; \ + *) (install-info --version) >/dev/null 2>&1;; \ + esac +am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP) +am__DIST_COMMON = $(srcdir)/Makefile.in +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +CC = @CC@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DSYMUTIL = @DSYMUTIL@ +DUMPBIN = @DUMPBIN@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +FGREP = @FGREP@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LD = @LD@ +LDFLAGS = @LDFLAGS@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LIPO = @LIPO@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ +MAKEINFO = @MAKEINFO@ +MANIFEST_TOOL = @MANIFEST_TOOL@ +MKDIR_P = @MKDIR_P@ +NM = @NM@ +NMEDIT = @NMEDIT@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +OTOOL = @OTOOL@ +OTOOL64 = @OTOOL64@ +OU_FEATURE_SET = @OU_FEATURE_SET@ +OU_NAMESPACE = @OU_NAMESPACE@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +RANLIB = @RANLIB@ +SED = @SED@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_AR = @ac_ct_AR@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +runstatedir = @runstatedir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ +EXTRA_DIST = assert.h \ + atomicflags.h \ + atomic.h \ + customization.h \ + enumarrays.h \ + features.h \ + flagsdefines.h \ + flags.h \ + inttypes.h \ + macros.h \ + malloc.h \ + namespace.h \ + platform.h \ + simpleflags.h \ + templates.h \ + threadlocalstorage.h \ + typewrapper.h + +all: all-am + +.SUFFIXES: +$(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign include/ou/Makefile'; \ + $(am__cd) $(top_srcdir) && \ + $(AUTOMAKE) --foreign include/ou/Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(am__aclocal_m4_deps): + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs +tags TAGS: + +ctags CTAGS: + +cscope cscopelist: + + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d "$(distdir)/$$file"; then \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \ + find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \ + fi; \ + cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \ + else \ + test -f "$(distdir)/$$file" \ + || cp -p $$d/$$file "$(distdir)/$$file" \ + || exit 1; \ + fi; \ + done +check-am: all-am +check: check-am +all-am: Makefile +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + if test -z '$(STRIP)'; then \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + install; \ + else \ + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \ + fi +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + -test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool mostlyclean-am + +distclean: distclean-am + -rm -f Makefile +distclean-am: clean-am distclean-generic + +dvi: dvi-am + +dvi-am: + +html: html-am + +html-am: + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-dvi-am: + +install-exec-am: + +install-html: install-html-am + +install-html-am: + +install-info: install-info-am + +install-info-am: + +install-man: + +install-pdf: install-pdf-am + +install-pdf-am: + +install-ps: install-ps-am + +install-ps-am: + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-generic mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: all all-am check check-am clean clean-generic clean-libtool \ + cscopelist-am ctags-am distclean distclean-generic \ + distclean-libtool distdir dvi dvi-am html html-am info info-am \ + install install-am install-data install-data-am install-dvi \ + install-dvi-am install-exec install-exec-am install-html \ + install-html-am install-info install-info-am install-man \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip installcheck installcheck-am installdirs \ + maintainer-clean maintainer-clean-generic mostlyclean \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags-am uninstall uninstall-am + +.PRECIOUS: Makefile + + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/libs/ode-0.16.1/ou/include/ou/assert.h b/libs/ode-0.16.1/ou/include/ou/assert.h new file mode 100644 index 0000000..d3147b3 --- /dev/null +++ b/libs/ode-0.16.1/ou/include/ou/assert.h @@ -0,0 +1,188 @@ +/************************************************************************* + * * + * ODER's Utilities Library. Copyright (C) 2008-2019 Oleh Derevenko. * + * All rights reserved. e-mail: odar@eleks.com (change all "a" to "e") * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 3 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE-LESSER.TXT. Since LGPL is the extension of GPL * + * the text of GNU General Public License is also provided for * + * your information in file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * (3) The zlib/libpng license that is included with this library in * + * the file LICENSE-ZLIB.TXT * + * * + * This library is distributed WITHOUT ANY WARRANTY, including implied * + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * + * See the files LICENSE.TXT and LICENSE-LESSER.TXT or LICENSE-BSD.TXT * + * or LICENSE-ZLIB.TXT for more details. * + * * + *************************************************************************/ + +#ifndef __OU_ASSERT_H_INCLUDED +#define __OU_ASSERT_H_INCLUDED + + +/** + * \file + * \brief Definitions of assertion checking macros. + * + * This file contains definitions of assertion failure check macros. + * These include \c OU_ASSERT, \c OU_VERIFY and \c OU_CHECK. + * Assertion failure handler is common for all three macros and is customizable. + * If assertion checks are not customized, system \c assert() function is used. + * \see CAssertionCheckCustomization + */ + + +#include +#include + + +/** + * \def OU_ASSERT + * \brief Defines a regular assertion check macro. + * + * \c OU_ASSERT defines a classic assertion check macro. Normally its expression + * is evaluated and if it is equal to \c false, assertion failure handler is invoked + * with \c AFS_ASSERT parameter. If assertion failure handler is not customized, + * the functionality of system \c assert() call is performed. + * If \c NDEBUG preprocessor symbol is defined, the macro expands to empty operator + * and expression of its argument is \e NOT evaluated. + * \note The expression is evaluated only once even though either custom handler or + * system \c assert() might be chosen to handle failure. + * \par + * \note The macro is designed so that "Condition" text is passed to customized + * handler and "OU__ASSERT_HANDLER(Condition)" is passed to \c assert() if + * handler is not customized. However new versions of GCC (starting from 4.3.0) + * seem to use modified macro expansion schema which formats macro \c OU__ASSERT_HANDLER + * into string after full expansion. + * + * \see OU_VERIFY + * \see OU_CHECK + * \see EASSERTIONFAILURESEVERITY + * \see CAssertionFailedProcedure + * \see CAssertionCheckCustomization + */ + +/** + * \def OU_VERIFY + * \brief Defines an assertion check macro which always evaluates its parameter. + * + * \c OU_VERIFY is similar to \c OU_ASSERT with exception that if \c NDEBUG preprocessor + * symbol is defined it still evaluates its parameter. + * The main purpose of this macro is to prevent "unused variable" compiler warning + * which would otherwise appear with \c OU_ASSERT macro used when \c NDEBUG is defined. + * + * \code + * bool bCallStatus = CallMyFunction(); + * // A compiler warning would be generated with OU_ASSERT if bCallStatus is + * // not used further in the code. + * OU_VERIFY(bCallStatus); + * \endcode + * + * \note It is not recommended to use \c OU_VERIFY with function calls directly + * if function result is not boolean, as otherwise in case of assertion failure + * it will be not possible to retrieve function result. + * \code + * // Incorrect! Call status will not be available in case of failure! + * OU_VERIFY(pthread_mutex_create(&attr) == EOK); + * + * // Correct. Call status can be retrieved from a variable. + * int iMutexCreateStatus = pthread_mutex_create(&attr); + * OU_VERIFY(iMutexCreateStatus == EOK); + * \endcode + * + * \see OU_ASSERT + * \see OU_CHECK + * \see EASSERTIONFAILURESEVERITY + * \see CAssertionFailedProcedure + * \see CAssertionCheckCustomization + */ + +/** + * \def OU_CHECK + * \brief Defines a hard assertion check macro. + * + * \c OU_CHECK evaluates its parameter and if the expression equals to \c false + * it invokes either a custom assertion failure handler with \c AFS_CHECK parameter + * or failure processing of system \c assert() function. The execution is not supposed + * to exit from assertion failure call. If it does (either because custom assertion + * failure handler returns or handler is not customized and \c assert() function has + * no effect because of \c NDEBUG symbol being defined), a write attempt to NULL + * pointer is performed to generate Access Violation exception or SIGSEGV signal. + * \c OU_CHECK is similar to \c OU_VERIFY in that it evaluates its parameter whether + * \c NDEBUG is defined or not. + * \note The expression is evaluated only once even though either custom handler or + * system \c assert() might be chosen to handle failure. + * \par + * \note The macro is designed so that "Condition" text is passed to customized + * handler and "OU__CHECK_HANDLER(Condition)" is passed to \c assert() if + * handler is not customized. However new versions of GCC (starting from 4.3.0) + * seem to use modified macro expansion schema which formats macro \c OU__CHECK_HANDLER + * into string after full expansion. + * + * \see OU_ASSERT + * \see OU_VERIFY + * \see EASSERTIONFAILURESEVERITY + * \see CAssertionFailedProcedure + * \see CAssertionCheckCustomization + */ + + +/* + * Implementation Note: + * 1) Fully qualified names must be used in macros as they might be + * used externally and forwarded from outside of _OU_NAMESPACE. + * 2) false || ... is necessary to suppress C4800 warning in MSVC. + */ + +#if defined(NDEBUG) + +#define OU_ASSERT(Condition) ((void)0) + +#define OU_VERIFY(Condition) ((void)(Condition)) + +#define OU_CHECK(Condition) (void)(false || (Condition) \ + || (!_OU_NAMESPACE::CAssertionCheckCustomization::GetAssertFailureCustomHandler() \ + || (_OU_NAMESPACE::CAssertionCheckCustomization::GetAssertFailureCustomHandler()( \ + _OU_NAMESPACE::AFS_CHECK, #Condition, __FILE__, __LINE__), false)) \ + || (*(volatile int *)0 = 0, false)) + + +#else // #if !defined(NDEBUG) + +#include + + +#define OU__ASSERT_HANDLER(Condition) (false || (Condition) \ + || (_OU_NAMESPACE::CAssertionCheckCustomization::GetAssertFailureCustomHandler() \ + && (_OU_NAMESPACE::CAssertionCheckCustomization::GetAssertFailureCustomHandler()( \ + _OU_NAMESPACE::AFS_ASSERT, #Condition, __FILE__, __LINE__), true))) + +#define OU__CHECK_HANDLER(Condition) (((bConditionValue = false || (Condition)), bConditionValue) \ + || (_OU_NAMESPACE::CAssertionCheckCustomization::GetAssertFailureCustomHandler() \ + && (_OU_NAMESPACE::CAssertionCheckCustomization::GetAssertFailureCustomHandler()( \ + _OU_NAMESPACE::AFS_CHECK, #Condition, __FILE__, __LINE__), true))) + + +#define OU_ASSERT(Condition) assert(OU__ASSERT_HANDLER(Condition)) + +#define OU_VERIFY(Condition) OU_ASSERT(Condition) + +#define OU_CHECK(Condition) { \ + bool bConditionValue; \ + assert(OU__CHECK_HANDLER(Condition)); \ + (void)(bConditionValue || (*(volatile int *)0 = 0, false)); \ +} + + +#endif // #if !defined(NDEBUG) + + +#endif // #ifndef __OU_ASSERT_H_INCLUDED diff --git a/libs/ode-0.16.1/ou/include/ou/atomic.h b/libs/ode-0.16.1/ou/include/ou/atomic.h new file mode 100644 index 0000000..2f90a70 --- /dev/null +++ b/libs/ode-0.16.1/ou/include/ou/atomic.h @@ -0,0 +1,1835 @@ +/************************************************************************* + * * + * ODER's Utilities Library. Copyright (C) 2008-2019 Oleh Derevenko. * + * All rights reserved. e-mail: odar@eleks.com (change all "a" to "e") * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 3 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE-LESSER.TXT. Since LGPL is the extension of GPL * + * the text of GNU General Public License is also provided for * + * your information in file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * (3) The zlib/libpng license that is included with this library in * + * the file LICENSE-ZLIB.TXT * + * * + * This library is distributed WITHOUT ANY WARRANTY, including implied * + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * + * See the files LICENSE.TXT and LICENSE-LESSER.TXT or LICENSE-BSD.TXT * + * or LICENSE-ZLIB.TXT for more details. * + * * + *************************************************************************/ + +#ifndef __OU_ATOMIC_H_INCLUDED +#define __OU_ATOMIC_H_INCLUDED + + +/** + * \file + * \brief Definitions of atomic (interlocked) API. + * + * Atomic (interlocked) functions are supposed to provide atomic operations on + * variables in multi-threaded environment without bringing synchronization objects in. + * Atomic functions can be used for implementing reliable reference counting, advanced + * synchronization objects, complex techniques of relaxed synchronization with minimum + * or no synchronization obejcts' usage. + * + * All atomic functions are implemented as memory barriers. + * + * On Windows, QNX, MacOS, AIX, SunOS atomic API is implemented via native OS calls. + * If atomic operation function are not provided (or not fully provided) by target OS, + * the missing operations are implemented with aid of other atomic functions or + * via mutex locks if that is not possible. The array of \c _OU_ATOMIC_MUTEX_COUNT + * (8 in current version) mutexes is used to decrease probability of several threads + * being competing for the same mutex lock and resulting necessity to block some + * of them during operation. + * + * All atomic API implementations are inlined, Exceptions are implementations via + * mutex locks for which it is not reasonable to generate inlined code. + * + * Atomic functions' prototypes were selected to to provide maximal possible + * functionality available on all the platforms mentioned above in common. Function + * names were chosen as a mix of Windows and UNIX naming traditions (more closely + * to Windows though). + * + * There are the following groups of API available: + * \li Arithmetic (\c AtomicIncrement, \c AtomicDecrement) + * \li Integer Exchange (\c AtomicExchange, \c AtomicExchangeAdd, \c AtomicCompareExchange) + * \li Bitwise (\c AtomicAnd, \c AtomicOr, \c AtomicXor) + * \li Pointer Exchange (\c AtomicExchangePointer, \c AtomicCompareExchangePointer) + * + * For Arithmetic and Bitwise groups along with \c AtomicExchangeAdd function there + * are "no result" variants available. These are written with \c NoResult suffix + * after function name and may operate faster on some platforms. However they do not + * provide operation results. + * + * Atomic functions of Arithmetic, Integer Exchange and Bitwise groups operate with + * 32-bit values regardless if build target address space is 32 or 64 bits wide. + * Pointer Exchange functions operate with pointer type and their argument can be + * both 32 or 64 bit value depending on build target. + * + * Generic x86 assembler implementation is provided for i486 and later processors. + * However it is never automatically selected. You must explicitly define + * \c _OU_ATOMIC_USE_X86_ASSEMBLER symbol in compiler options to select that + * implementation. The option can only be used if \c _OU_TARGET_OS is equal to + * \c _OU_TARGET_OS_GENUNIX. If the symbol is defined for any other target, + * it is silently ignored. + * \warning + * Never use assembler implementation on systems that provide native atomic API! + * + * Atomic API may require initialization before first use and finalization on program + * exit. The initialization may be necessary when operating system does not provide + * sufficient functionality to implement all the operations via native calls. However, + * to maintain code portability it is recommended that initialization/finalization + * functions are always called. + * + * API initialization and finalization calls use reference counting mechanism and + * thus may be invoked several times from different subsystems. Initialization and + * finalization is \e not \e thread \e safe and should be performed from main thread + * only. + */ + +#include + + +#if _OU_FEATURE_SET >= _OU_FEATURE_SET_ATOMICS + +#include +#include +#include + + +/** + * \typedef atomicord32 + * \brief An uniform type for 32-bit values to be used as atomic operations' arguments. + * + * This type is supposed to be used for all the variables that store atomic values. + * The word "int" was by intent avoided in its name to emphasize that the type + * needs not necessary to be a signed integer. It might be either signed or unsigned + * depending on target platform. The only information which could be relied on is + * that the type will always be 32 bit wide, regardless if target platform is a + * 32 or 64-bit one. + * + * Any arithmetic operations should be avoided with type \c atomicord32. + * Instead, the wrapper functions should be used to access the value. The function should + * cast value type to \c atomicord32 in parameters and cast result back to value type. + * \code + * int ExchangeValue(volatile atomicord32 *paoDestination, int iExchange) + * { + * return (int)AtomicExchange(paoDestination, (atomicord32)iExchange); + * } + * \endcode + * \see atomicptr + */ + +/** + * \typedef atomicptr + * \brief An uniform type for pointer values to be used as atomic operations' arguments + * + * The type is to be used for those function which operate with pointers rather + * than integers. The size of \c atomicptr is platform dependent, just like the + * size of the pointer and equals 4 bytes on 32-bit platforms and 8 bytes on 64-bit ones. + * \see atomicord32 + */ + +/** + * \fn atomicord32 _OU_CONVENTION_API AtomicIncrement(volatile atomicord32 *paoDestination) + * \brief Increments the destination and returns its new value. + * \param paoDestination A pointer to a variable to be incremented. + * \return A value of variable pointed to by \a paoDestination after the increment. + * + * The function implements functionality of \c InterlockedIncrement from Win32 API. + * It is most commonly used for reference counting. + * \see AtomicDecrement + */ + +/** + * \fn atomicord32 _OU_CONVENTION_API AtomicDecrement(volatile atomicord32 *paoDestination) + * \brief Decrements the destination and returns its new value. + * \param paoDestination A pointer to a variable to be decremented. + * \return A value of variable pointed to by \a paoDestination after the decrement. + * + * The function implements functionality of \c InterlockedDecrement from Win32 API. + * It is most commonly used for reference counting. + * \see AtomicIncrement + */ + +/** + * \fn void _OU_CONVENTION_API AtomicStore(volatile atomicord32 *paoDestination, atomicord32 aoValue) + * \brief Stores the value in destination. + * \param paoDestination A pointer to a variable the data is to be stored in. + * \param aoValue A value to be stored. + * + * The function performs atomic store of \a aoValue value in the memory location + * pointed to by \a paoDestination. + */ + +/** + * \fn atomicord32 _OU_CONVENTION_API AtomicExchange(volatile atomicord32 *paoDestination, atomicord32 aoExchange) + * \brief Stores new value in destination and returns old value of destination. + * \param paoDestination A pointer to a variable the data is to be exchanged with. + * \param aoExchange A value to be used for exchange. + * \return Previous value of variable pointed to by \a paoDestination. + * + * The function performs atomic exchange of \a aoExchange value with memory location + * pointed to by \a paoDestination. Most common uses are relaxed synchronization + * and shared value extraction. + * \see AtomicCompareExchange + */ + +/** + * \fn atomicord32 _OU_CONVENTION_API AtomicExchangeAdd(volatile atomicord32 *paoDestination, atomicord32 aoAddend) + * \brief Assigns sum of addend and existing destination value to the destination + * and returns original value of destination. + * \param paoDestination A pointer to a variable the value is to be added to. + * \param aoAddend An addend to be used in operation. + * \return Original value of variable pointed to by \a paoDestination. + * + * The function computes sum of \a aoAddend and location pointed to by \a paoDestination + * stores it in the location and returns original value instead. The function is + * close to both exchange and increment groups by semantics but it has been + * put into exchange group because it returns original value of the destination. + * Also, the function was not named \c AtomicAdd to avoid similarity with \c AtomicAnd. + * One of supposed applications is the resource counting. + * \see AtomicIncrement + * \see AtomicDecrement + */ + +/** + * \fn bool _OU_CONVENTION_API AtomicCompareExchange(volatile atomicord32 *paoDestination, atomicord32 aoComparand, atomicord32 aoExchange) + * \brief Compares comparand with destination and stores a new value if comparand + * and destination match; returns if the assignment was performed or not. + * \param paoDestination A pointer to a variable the data is to be compared and assigned to. + * \param aoComparand A value to be used for comparison. + * \param aoExchange A new value to be used for assignment. + * \return \c true if exchange was performed and \c false otherwise. + * + * The function performs comparison of \a aoComparand value with the value pointed + * by \a paoDestination. If the values match an \a aoExchange is assigned to + * destination location. If values do not match, the restination remains unchanged. + * Function returns boolean status whether the match and assignment occurred or not. + * The most common uses are relaxed synchronization and construction of LIFO lists. + * \see AtomicExchange + */ + +/** + * \fn atomicord32 _OU_CONVENTION_API AtomicAnd(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) + * \brief Applies a mask with bitwise AND to the destination and returns original + * value of destination. + * \param paoDestination A pointer to a variable the bitmask is to be applied to. + * \param aoBitMask A bitmask to be used in operation. + * \return Original value of variable pointed to by \a paoDestination. + * + * \c AtomicAnd updates variable pointed to by \a paoDestination with result of + * bitwise AND of \a aoBitMask and existing \a paoDestination target. The result + * is original value that was pointed to by \a paoDestination before the operation + * was performed. Common applications are object state manipulations. + * \see AtomicOr + * \see AtomicXor + */ + +/** + * \fn atomicord32 _OU_CONVENTION_API AtomicOr(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) + * \brief Applies a mask with bitwise OR to the destination and returns original + * value of destination. + * \param paoDestination A pointer to a variable the bitmask is to be applied to. + * \param aoBitMask A bitmask to be used in operation. + * \return Original value of variable pointed to by \a paoDestination. + * + * \c AtomicOr updates variable pointed to by \a paoDestination with result of + * bitwise OR of \a aoBitMask and existing \a paoDestination target. The result + * is original value that was pointed to by \a paoDestination before the operation + * was performed. Common applications are object state manipulations. + * \see AtomicAnd + * \see AtomicXor + */ + +/** + * \fn atomicord32 _OU_CONVENTION_API AtomicXor(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) + * \brief Applies a mask with bitwise XOR to the destination and returns original + * value of destination. + * \param paoDestination A pointer to a variable the bitmask is to be applied to. + * \param aoBitMask A bitmask to be used in operation. + * \return Original value of variable pointed to by \a paoDestination. + * + * \c AtomicXor updates variable pointed to by \a paoDestination with result of + * bitwise XOR of \a aoBitMask and existing \a paoDestination target. The result + * is original value that was pointed to by \a paoDestination before the operation + * was performed. Common applications are object state manipulations. + * \see AtomicAnd + * \see AtomicOr + */ + +/** + * \fn void _OU_CONVENTION_API AtomicStorePointer(volatile atomicptr *papDestination, atomicptr apValue) + * \brief The function is identical to \c AtomicStore except that it operates + * with pointers rather than 32-bit integers. + * \see AtomicStore + */ + +/** + * \fn atomicptr _OU_CONVENTION_API AtomicExchangePointer(volatile atomicptr *papDestination, atomicptr apExchange) + * \brief The function is identical to \c AtomicExchange except that it operates + * with pointers rather than 32-bit integers. + * \see AtomicExchange + */ + +/** + * \fn bool _OU_CONVENTION_API AtomicCompareExchangePointer(volatile atomicptr *papDestination, atomicptr apComparand, atomicptr apExchange) + * \brief The function is identical to \c AtomicCompareExchange except that it operates + * with pointers rather than 32-bit integers. + * \see AtomicCompareExchange + */ + +/** + * \fn void _OU_CONVENTION_API AtomicIncrementNoResult(volatile atomicord32 *paoDestination) + * \brief The function is identical to \c AtomicIncrement but does not return a result. + * + * The function implementation can be faster on some platforms and it is recommended + * to use "NoResult" variants in cases when the result of operation or previous value + * of destination is not used. + * \see AtomicIncrement + */ + +/** + * \fn void _OU_CONVENTION_API AtomicDecrementNoResult(volatile atomicord32 *paoDestination) + * \brief The function is identical to \c AtomicDecrement but does not return a result. + * + * The function implementation can be faster on some platforms and it is recommended + * to use "NoResult" variants in cases when the result of operation or previous value + * of destination is not used. + * \see AtomicDecrement + */ + +/** + * \fn void _OU_CONVENTION_API AtomicExchangeAddNoResult(volatile atomicord32 *paoDestination, atomicord32 aoAddend) + * \brief The function is identical to \c AtomicExchangeAdd but does not return a result. + * + * The function implementation can be faster on some platforms and it is recommended + * to use "NoResult" variants in cases when the result of operation or previous value + * of destination is not used. + * \see AtomicExchangeAdd + */ + +/** + * \fn void _OU_CONVENTION_API AtomicAndNoResult(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) + * \brief The function is identical to \c AtomicAnd but does not return a result. + * + * The function implementation can be faster on some platforms and it is recommended + * to use "NoResult" variants in cases when the result of operation or previous value + * of destination is not used. + * \see AtomicAnd + */ + +/** + * \fn void _OU_CONVENTION_API AtomicOrNoResult(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) + * \brief The function is identical to \c AtomicOr but does not return a result. + * + * The function implementation can be faster on some platforms and it is recommended + * to use "NoResult" variants in cases when the result of operation or previous value + * of destination is not used. + * \see AtomicOr + */ + +/** + * \fn void _OU_CONVENTION_API AtomicXorNoResult(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) + * \brief The function is identical to \c AtomicXor but does not return a result. + * + * The function implementation can be faster on some platforms and it is recommended + * to use "NoResult" variants in cases when the result of operation or previous value + * of destination is not used. + * \see AtomicXor + */ + +/** + * \fn void _OU_CONVENTION_API AtomicReadReorderBarrier() + * \brief The function prevents both the compiler and the processor architecture + * from reordering memory read operations across the barrier call. + */ + + +/** + * \fn bool _OU_CONVENTION_API InitializeAtomicAPI() + * \brief Performs initialization tasks to allow using atomic functions. + * \return Boolean initialization status. + * + * The function is required to be called before first use of atomic functions. + * The initialization uses reference counting, so multiple calls to \c InitializeAtomicAPI + * are allowed. However the counter is not thread safe. Therefore it is recommended + * that the function is always called from main thread on program startup or + * library initialization. + * + * The function returns initialization status. If initialization succeeds, + * \c FinalizeAtomicAPI is to be called for each call to \c InitializeAtomicAPI after + * atomic functions are not needed any more. If \c InitializeAtomicAPI returns + * \c false, the atomic functions may not be used and \c FinalizeAtomicAPI must not be called. + * \see FinalizeAtomicAPI + */ + +/** + * \fn void _OU_CONVENTION_API FinalizeAtomicAPI() + * \brief Finalizes objects and frees the memory that might be used to provide + * functionality of atomic functions. + * + * The function is to be called on program exit or library client detach to + * release resources that might be allocated to support functionality of Atomic... + * functions. The function must be called once for every successful call to + * \c InitializeAtomicAPI. \c FinalizeAtomicAPI can not fail. + * \see InitializeAtomicAPI + */ + + +BEGIN_NAMESPACE_OU(); + + +////////////////////////////////////////////////////////////////////////// +// Windows implementation + +#if _OU_TARGET_OS == _OU_TARGET_OS_WINDOWS + + +END_NAMESPACE_OU(); + + +#include +#include + + +BEGIN_NAMESPACE_OU(); + + +typedef ULONG atomicord32; +typedef PVOID atomicptr; + + +#if _OU_COMPILER == _OU_COMPILER_MSVC && _OU_COMPILER_VERSION == _OU_COMPILER_VERSION_MSVC1998 + +#define __ou_intlck_value_t LONG +#define __ou_intlck_target_t LPLONG +#define __ou_xchgadd_target_t LPLONG +#define __ou_cmpxchg_value_t PVOID +#define __ou_cmpxchg_target_t PVOID * + + +#elif _OU_COMPILER == _OU_COMPILER_GCC + +#define __ou_intlck_value_t LONG +#define __ou_intlck_target_t LPLONG +#define __ou_xchgadd_target_t LPLONG +#define __ou_cmpxchg_value_t LONG +#define __ou_cmpxchg_target_t LPLONG + + +#else // other compilers + +#define __ou_intlck_value_t LONG +#define __ou_intlck_target_t volatile LONG * +#define __ou_xchgadd_target_t LPLONG +#define __ou_cmpxchg_value_t LONG +#define __ou_cmpxchg_target_t volatile LONG * + + +#endif // #if _OU_COMPILER == _OU_COMPILER_GCC + + +#define __OU_ATOMIC_ORD32_FUNCTIONS_DEFINED + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicIncrement(volatile atomicord32 *paoDestination) +{ + return ::InterlockedIncrement((__ou_intlck_target_t)paoDestination); +} + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicDecrement(volatile atomicord32 *paoDestination) +{ + return ::InterlockedDecrement((__ou_intlck_target_t)paoDestination); +} + + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicExchange(volatile atomicord32 *paoDestination, atomicord32 aoExchange) +{ + return ::InterlockedExchange((__ou_intlck_target_t)paoDestination, aoExchange); +} + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicExchangeAdd(volatile atomicord32 *paoDestination, atomicord32 aoAddend) +{ + return ::InterlockedExchangeAdd((__ou_xchgadd_target_t)paoDestination, aoAddend); +} + +static _OU_ALWAYSINLINE bool _OU_CONVENTION_API +/*bool */AtomicCompareExchange(volatile atomicord32 *paoDestination, atomicord32 aoComparand, atomicord32 aoExchange) +{ + return (aoComparand == (atomicord32)::InterlockedCompareExchange((__ou_cmpxchg_target_t)paoDestination, (__ou_cmpxchg_value_t)aoExchange, (__ou_cmpxchg_value_t)aoComparand)); +} + + +#define __OU_ATOMIC_BIT_FUNCTIONS_DEFINED + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicAnd(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + atomicord32 aoOldValue = *paoDestination; + + while (true) + { + atomicord32 aoNewValue = (atomicord32)::InterlockedCompareExchange((__ou_cmpxchg_target_t)paoDestination, (__ou_cmpxchg_value_t)(aoOldValue & aoBitMask), (__ou_cmpxchg_value_t)aoOldValue); + + if (aoNewValue == aoOldValue) + { + break; + } + + aoOldValue = aoNewValue; + } + + return aoOldValue; +} + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicOr(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + atomicord32 aoOldValue = *paoDestination; + + while (true) + { + atomicord32 aoNewValue = (atomicord32)::InterlockedCompareExchange((__ou_cmpxchg_target_t)paoDestination, (__ou_cmpxchg_value_t)(aoOldValue | aoBitMask), (__ou_cmpxchg_value_t)aoOldValue); + + if (aoNewValue == aoOldValue) + { + break; + } + + aoOldValue = aoNewValue; + } + + return aoOldValue; +} + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicXor(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + atomicord32 aoOldValue = *paoDestination; + + while (true) + { + atomicord32 aoNewValue = (atomicord32)::InterlockedCompareExchange((__ou_cmpxchg_target_t)paoDestination, (__ou_cmpxchg_value_t)(aoOldValue ^ aoBitMask), (__ou_cmpxchg_value_t)aoOldValue); + + if (aoNewValue == aoOldValue) + { + break; + } + + aoOldValue = aoNewValue; + } + + return aoOldValue; +} + + +#define __OU_ATOMIC_PTR_FUNCTIONS_DEFINED + +static _OU_ALWAYSINLINE atomicptr _OU_CONVENTION_API +/*atomicptr */AtomicExchangePointer(volatile atomicptr *papDestination, atomicptr apExchange) +{ +#if _OU_TARGET_BITS == _OU_TARGET_BITS_32 + + return (atomicptr)(ptrdiff_t)::InterlockedExchange((__ou_intlck_target_t)papDestination, (__ou_intlck_value_t)(ptrdiff_t)apExchange); + + +#else // #if _OU_TARGET_BITS == _OU_TARGET_BITS_64 + + return ::InterlockedExchangePointer(papDestination, apExchange); + + +#endif // #if _OU_TARGET_BITS == ... +} + +static _OU_ALWAYSINLINE bool _OU_CONVENTION_API +/*bool */AtomicCompareExchangePointer(volatile atomicptr *papDestination, atomicptr apComparand, atomicptr apExchange) +{ +#if _OU_TARGET_BITS == _OU_TARGET_BITS_32 + + return (apComparand == (atomicptr)(ptrdiff_t)::InterlockedCompareExchange((__ou_cmpxchg_target_t)papDestination, (__ou_cmpxchg_value_t)(ptrdiff_t)apExchange, (__ou_cmpxchg_value_t)(ptrdiff_t)apComparand)); + + +#else // #if !defined(__OU_ATOMIC_WINDOWS_OLD_STYLE_PARAMS) + + return (apComparand == ::InterlockedCompareExchangePointer(papDestination, apExchange, apComparand)); + + +#endif // #if !defined(__OU_ATOMIC_WINDOWS_OLD_STYLE_PARAMS) +} + + +#if _OU_COMPILER == _OU_COMPILER_MSVC + +#if (_OU_TARGET_ARCH == _OU_TARGET_ARCH_X86 || _OU_TARGET_ARCH == _OU_TARGET_ARCH_X64) + +#define __OU_ATOMIC_READREORDERBARRIER_FUNCTION_DEFINED + +#include + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicReadReorderBarrier() +{ + _ReadBarrier(); +} + + +#endif // #if (_OU_TARGET_ARCH == _OU_TARGET_ARCH_X86 || _OU_TARGET_ARCH == _OU_TARGET_ARCH_X64) + + +#endif // #if _OU_COMPILER == _OU_COMPILER_MSVC + + +#undef __ou_intlck_value_t +#undef __ou_intlck_target_t +#undef __ou_xchgadd_target_t +#undef __ou_cmpxchg_value_t +#undef __ou_cmpxchg_target_t + + +#endif // #if _OU_TARGET_OS == _OU_TARGET_OS_WINDOWS + + +////////////////////////////////////////////////////////////////////////// +// QNX implementation + +#if _OU_TARGET_OS == _OU_TARGET_OS_QNX + +END_NAMESPACE_OU(); + + +#include +#include _NTO_CPU_HDR_(smpxchg.h) + + +BEGIN_NAMESPACE_OU(); + +typedef unsigned int atomicord32; +typedef void *atomicptr; + + +#define __OU_ATOMIC_ORD32_FUNCTIONS_DEFINED + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicIncrement(volatile atomicord32 *paoDestination) +{ + return (atomic_add_value(paoDestination, 1U) + 1U); +} + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicDecrement(volatile atomicord32 *paoDestination) +{ + return (atomic_sub_value(paoDestination, 1U) - 1U); +} + + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicExchange(volatile atomicord32 *paoDestination, atomicord32 aoExchange) +{ + return _smp_xchg(paoDestination, aoExchange); +} + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicExchangeAdd(volatile atomicord32 *paoDestination, atomicord32 aoAddend) +{ + return atomic_add_value(paoDestination, aoAddend); +} + +static _OU_ALWAYSINLINE bool _OU_CONVENTION_API +/*bool */AtomicCompareExchange(volatile atomicord32 *paoDestination, atomicord32 aoComparand, atomicord32 aoExchange) +{ + return (aoComparand == (atomicord32)_smp_cmpxchg(paoDestination, aoComparand, aoExchange)); +} + + +#define __OU_ATOMIC_BIT_FUNCTIONS_DEFINED + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicAnd(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + return atomic_clr_value(paoDestination, ~aoBitMask); +} + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicOr(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + return atomic_set_value(paoDestination, aoBitMask); +} + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicXor(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + return atomic_toggle_value(paoDestination, aoBitMask); +} + + +#define __OU_ATOMIC_ORD32_NORESULT_FUNCTIONS_DEFINED + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicIncrementNoResult(volatile atomicord32 *paoDestination) +{ + atomic_add(paoDestination, 1U); +} + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicDecrementNoResult(volatile atomicord32 *paoDestination) +{ + atomic_sub(paoDestination, 1U); +} + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicExchangeAddNoResult(volatile atomicord32 *paoDestination, atomicord32 aoAddend) +{ + atomic_add(paoDestination, aoAddend); +} + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicAndNoResult(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + atomic_clr(paoDestination, ~aoBitMask); +} + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicOrNoResult(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + atomic_set(paoDestination, aoBitMask); +} + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicXorNoResult(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + atomic_toggle(paoDestination, aoBitMask); +} + + +#endif // #if _OU_TARGET_OS == _OU_TARGET_OS_QNX + + +////////////////////////////////////////////////////////////////////////// +// Mac implementation + +#if _OU_TARGET_OS == _OU_TARGET_OS_MAC || _OU_TARGET_OS == _OU_TARGET_OS_IOS + +#if MAC_OS_X_VERSION >= 1040 + + +END_NAMESPACE_OU(); + + +#include + + +BEGIN_NAMESPACE_OU(); + + +typedef uint32_t atomicord32; +typedef void *atomicptr; + + +#define __ou_intlck_target_t volatile int32_t * +#define __ou_xchgadd_target_t volatile int32_t * +#define __ou_cmpxchg_value_t int32_t +#define __ou_cmpxchg_target_t volatile int32_t * +#define __ou_bitmsk_target_t volatile uint32_t * + + +#define __OU_ATOMIC_ORD32_FUNCTIONS_DEFINED + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicIncrement(volatile atomicord32 *paoDestination) +{ + return OSAtomicIncrement32Barrier((__ou_intlck_target_t)paoDestination); +} + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicDecrement(volatile atomicord32 *paoDestination) +{ + return OSAtomicDecrement32Barrier((__ou_intlck_target_t)paoDestination); +} + + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicExchange(volatile atomicord32 *paoDestination, atomicord32 aoExchange) +{ + __ou_cmpxchg_value_t aoOldValue = *paoDestination; + + /* + * Implementation Note: + * It is safe to use compare-and-swap without memory barrier for subsequent attempts + * because current thread had already had a barrier and does not have any additional + * memory access until function exit. On the other hand it is expected that other + * threads will be using this API set for manipulations with paoDestination as well + * and hence will not issue writes after/without memory barrier. + */ + for (bool bSwapExecuted = OSAtomicCompareAndSwap32Barrier(aoOldValue, aoExchange, (__ou_cmpxchg_target_t)paoDestination); + !bSwapExecuted; bSwapExecuted = OSAtomicCompareAndSwap32(aoOldValue, aoExchange, (__ou_cmpxchg_target_t)paoDestination)) + { + aoOldValue = *paoDestination; + } + + return aoOldValue; +} + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicExchangeAdd(volatile atomicord32 *paoDestination, atomicord32 aoAddend) +{ + return (OSAtomicAdd32Barrier(aoAddend, (__ou_xchgadd_target_t)paoDestination) - aoAddend); +} + +static _OU_ALWAYSINLINE bool _OU_CONVENTION_API +/*bool */AtomicCompareExchange(volatile atomicord32 *paoDestination, atomicord32 aoComparand, atomicord32 aoExchange) +{ + return OSAtomicCompareAndSwap32Barrier(aoComparand, aoExchange, (__ou_cmpxchg_target_t)paoDestination); +} + + +#if MAC_OS_X_VERSION >= 1050 + +#define __OU_ATOMIC_BIT_FUNCTIONS_DEFINED + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicAnd(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + return OSAtomicAnd32OrigBarrier(aoBitMask, (__ou_bitmsk_target_t)paoDestination); +} + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicOr(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + return OSAtomicOr32OrigBarrier(aoBitMask, (__ou_bitmsk_target_t)paoDestination); +} + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicXor(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + return OSAtomicXor32OrigBarrier(aoBitMask, (__ou_bitmsk_target_t)paoDestination); +} + + +#else // #if MAC_OS_X_VERSION < 1050 (...&& MAC_OS_X_VERSION >= 1040) + +#define __OU_ATOMIC_BIT_FUNCTIONS_DEFINED + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicAnd(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + atomicord32 aoOldValue = *paoDestination; + + /* + * Implementation Note: + * It is safe to use compare-and-swap without memory barrier for subsequent attempts + * because current thread had already had a barrier and does not have any additional + * memory access until function exit. On the other hand it is expected that other + * threads will be using this API set for manipulations with paoDestination as well + * and hence will not issue writes after/without memory barrier. + */ + for (bool bSwapExecuted = OSAtomicCompareAndSwap32Barrier(aoOldValue, (aoOldValue & aoBitMask), paoDestination); + !bSwapExecuted; bSwapExecuted = OSAtomicCompareAndSwap32(aoOldValue, (aoOldValue & aoBitMask), paoDestination)) + { + aoOldValue = *paoDestination; + } + + return aoOldValue; +} + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicOr(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + atomicord32 aoOldValue = *paoDestination; + + /* + * Implementation Note: + * It is safe to use compare-and-swap without memory barrier for subsequent attempts + * because current thread had already had a barrier and does not have any additional + * memory access until function exit. On the other hand it is expected that other + * threads will be using this API set for manipulations with paoDestination as well + * and hence will not issue writes after/without memory barrier. + */ + for (bool bSwapExecuted = OSAtomicCompareAndSwap32Barrier(aoOldValue, (aoOldValue | aoBitMask), paoDestination); + !bSwapExecuted; bSwapExecuted = OSAtomicCompareAndSwap32(aoOldValue, (aoOldValue | aoBitMask), paoDestination)) + { + aoOldValue = *paoDestination; + } + + return aoOldValue; +} + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicXor(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + return (OSAtomicXor32Barrier(aoBitMask, (__ou_bitmsk_target_t)paoDestination) ^ aoBitMask); +} + + +#endif // #if MAC_OS_X_VERSION < 1050 (...&& MAC_OS_X_VERSION >= 1040) + + +#if MAC_OS_X_VERSION >= 1050 + +#define __OU_ATOMIC_PTR_FUNCTIONS_DEFINED + +static _OU_ALWAYSINLINE atomicptr _OU_CONVENTION_API +/*atomicptr */AtomicExchangePointer(volatile atomicptr *papDestination, atomicptr apExchange) +{ + atomicptr apOldValue = *papDestination; + + /* + * Implementation Note: + * It is safe to use compare-and-swap without memory barrier for subsequent attempts + * because current thread had already had a barrier and does not have any additional + * memory access until function exit. On the other hand it is expected that other + * threads will be using this API set for manipulations with papDestination as well + * and hence will not issue writes after/without memory barrier. + */ + for (bool bSwapExecuted = OSAtomicCompareAndSwapPtrBarrier(apOldValue, apExchange, papDestination); + !bSwapExecuted; bSwapExecuted = OSAtomicCompareAndSwapPtr(apOldValue, apExchange, papDestination)) + { + apOldValue = *papDestination; + } + + return apOldValue; +} + +static _OU_ALWAYSINLINE bool _OU_CONVENTION_API +/*bool */AtomicCompareExchangePointer(volatile atomicptr *papDestination, atomicptr apComparand, atomicptr apExchange) +{ + return OSAtomicCompareAndSwapPtrBarrier(apComparand, apExchange, papDestination); +} + + +#endif // #if MAC_OS_X_VERSION >= 1050 + + +#define __OU_ATOMIC_ORD32_NORESULT_FUNCTIONS_DEFINED + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicIncrementNoResult(volatile atomicord32 *paoDestination) +{ + OSAtomicIncrement32Barrier((__ou_intlck_target_t)paoDestination); +} + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicDecrementNoResult(volatile atomicord32 *paoDestination) +{ + OSAtomicDecrement32Barrier((__ou_intlck_target_t)paoDestination); +} + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicExchangeAddNoResult(volatile atomicord32 *paoDestination, atomicord32 aoAddend) +{ + OSAtomicAdd32Barrier(aoAddend, (__ou_xchgadd_target_t)paoDestination); +} + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicAndNoResult(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + OSAtomicAnd32Barrier(aoBitMask, (__ou_bitmsk_target_t)paoDestination); +} + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicOrNoResult(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + OSAtomicOr32Barrier(aoBitMask, (__ou_bitmsk_target_t)paoDestination); +} + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicXorNoResult(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + OSAtomicXor32Barrier(aoBitMask, (__ou_bitmsk_target_t)paoDestination); +} + + +#endif // #if MAC_OS_X_VERSION >= 1040 + + +#undef __ou_bitmsk_target_t +#undef __ou_cmpxchg_target_t +#undef __ou_cmpxchg_value_t +#undef __ou_xchgadd_target_t +#undef __ou_intlck_target_t + + +#endif // #if _OU_TARGET_OS == _OU_TARGET_OS_MAC + + +////////////////////////////////////////////////////////////////////////// +// AIX implementation + +#if _OU_TARGET_OS == _OU_TARGET_OS_AIX + + +END_NAMESPACE_OU(); + + +#include + + +BEGIN_NAMESPACE_OU(); + + +typedef unsigned int atomicord32; +typedef void *atomicptr; + +#define __ou_cas_value_t int +#define __ou_caslp_value_t long + + +#define __OU_ATOMIC_ORD32_FUNCTIONS_DEFINED + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicIncrement(volatile atomicord32 *paoDestination) +{ + return (fetch_and_add((atomic_p)paoDestination, 1) + 1); +} + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicDecrement(volatile atomicord32 *paoDestination) +{ + return (fetch_and_add((atomic_p)paoDestination, -1) - 1); +} + + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicExchange(volatile atomicord32 *paoDestination, atomicord32 aoExchange) +{ + __ou_cas_value_t aoOldValue = *paoDestination; + + while (!compare_and_swap((atomic_p)paoDestination, &aoOldValue, aoExchange)) + { + // Do nothing + } + + return aoOldValue; +} + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicExchangeAdd(volatile atomicord32 *paoDestination, atomicord32 aoAddend) +{ + return fetch_and_add((atomic_p)paoDestination, aoAddend); +} + +static _OU_ALWAYSINLINE bool _OU_CONVENTION_API +/*bool */AtomicCompareExchange(volatile atomicord32 *paoDestination, atomicord32 aoComparand, atomicord32 aoExchange) +{ + __ou_cas_value_t aoOldValue = aoComparand; + + return compare_and_swap((atomic_p)paoDestination, &aoOldValue, aoExchange); +} + + +#define __OU_ATOMIC_BIT_FUNCTIONS_DEFINED + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicAnd(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + return fetch_and_and((atomic_p)paoDestination, aoBitMask); +} + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicOr(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + return fetch_and_or((atomic_p)paoDestination, aoBitMask); +} + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicXor(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + volatile __ou_cas_value_t aoOldValue = *paoDestination; + + while (!compare_and_swap((atomic_p)paoDestination, &aoOldValue, aoOldValue ^ aoBitMask)) + { + // Do nothing + } + + return aoOldValue; +} + + +#if _OU_TARGET_BITS == _OU_TARGET_BITS_64 // Otherwise functions will be forwarded to ord32 further in this file + +#define __OU_ATOMIC_PTR_FUNCTIONS_DEFINED + +static _OU_ALWAYSINLINE atomicptr _OU_CONVENTION_API +/*atomicptr */AtomicExchangePointer(volatile atomicptr *papDestination, atomicptr apExchange) +{ + __ou_caslp_value_t liOldValue = (__ou_caslp_value_t)*papDestination; + + while (!compare_and_swaplp((atomic_l)papDestination, &liOldValue, (__ou_caslp_value_t)apExchange)) + { + // Do nothing + } + + return liOldValue; +} + +static _OU_ALWAYSINLINE bool _OU_CONVENTION_API +/*bool */AtomicCompareExchangePointer(volatile atomicptr *papDestination, atomicptr apComparand, atomicptr apExchange) +{ + __ou_caslp_value_t liOldValue = (__ou_caslp_value_t)apComparand; + + return compare_and_swaplp((atomic_l)papDestination, &liOldValue, (__ou_caslp_value_t)apExchange); +} + + +#endif // #if _OU_TARGET_BITS == _OU_TARGET_BITS_64 + + +#undef __ou_caslp_value_t +#undef __ou_cas_value_t + + +#endif // #if _OU_TARGET_OS == _OU_TARGET_OS_AIX + + +////////////////////////////////////////////////////////////////////////// +// SunOS implementation + +#if _OU_TARGET_OS == _OU_TARGET_OS_SUNOS + + +END_NAMESPACE_OU(); + + +#include + + +BEGIN_NAMESPACE_OU(); + + +typedef uint32_t atomicord32; +typedef void *atomicptr; + + +#define __OU_ATOMIC_ORD32_FUNCTIONS_DEFINED + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicIncrement(volatile atomicord32 *paoDestination) +{ + return atomic_inc_32_nv(paoDestination); +} + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicDecrement(volatile atomicord32 *paoDestination) +{ + return atomic_dec_32_nv(paoDestination); +} + + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicExchange(volatile atomicord32 *paoDestination, atomicord32 aoExchange) +{ + return atomic_swap_32(paoDestination, aoExchange); +} + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicExchangeAdd(volatile atomicord32 *paoDestination, atomicord32 aoAddend) +{ + return (atomic_add_32_nv(paoDestination, aoAddend) - aoAddend); +} + +static _OU_ALWAYSINLINE bool _OU_CONVENTION_API +/*bool */AtomicCompareExchange(volatile atomicord32 *paoDestination, atomicord32 aoComparand, atomicord32 aoExchange) +{ + return (aoComparand == atomic_cas_32(paoDestination, aoComparand, aoExchange)); +} + + +#define __OU_ATOMIC_BIT_FUNCTIONS_DEFINED + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicAnd(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + atomicord32 aoOldValue = *paoDestination; + + while (true) + { + atomicord32 aoNewValue = atomic_cas_32(paoDestination, aoOldValue, aoOldValue & aoBitMask); + + if (aoNewValue == aoOldValue) + { + break; + } + + aoOldValue = aoNewValue; + } + + return aoOldValue; +} + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicOr(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + atomicord32 aoOldValue = *paoDestination; + + while (true) + { + atomicord32 aoNewValue = atomic_cas_32(paoDestination, aoOldValue, aoOldValue | aoBitMask); + + if (aoNewValue == aoOldValue) + { + break; + } + + aoOldValue = aoNewValue; + } + + return aoOldValue; +} + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicXor(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + atomicord32 aoOldValue = *paoDestination; + + while (true) + { + atomicord32 aoNewValue = atomic_cas_32(paoDestination, aoOldValue, aoOldValue ^ aoBitMask); + + if (aoNewValue == aoOldValue) + { + break; + } + + aoOldValue = aoNewValue; + } + + return aoOldValue; +} + + +#define __OU_ATOMIC_PTR_FUNCTIONS_DEFINED + +static _OU_ALWAYSINLINE atomicptr _OU_CONVENTION_API +/*atomicptr */AtomicExchangePointer(volatile atomicptr *papDestination, atomicptr apExchange) +{ + return atomic_swap_ptr(papDestination, apExchange); +} + +static _OU_ALWAYSINLINE bool _OU_CONVENTION_API +/*bool */AtomicCompareExchangePointer(volatile atomicptr *papDestination, atomicptr apComparand, atomicptr apExchange) +{ + return (apComparand == atomic_cas_ptr(papDestination, apComparand, apExchange)); +} + + +#define __OU_ATOMIC_ORD32_NORESULT_FUNCTIONS_DEFINED + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicIncrementNoResult(volatile atomicord32 *paoDestination) +{ + atomic_inc_32(paoDestination); +} + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicDecrementNoResult(volatile atomicord32 *paoDestination) +{ + atomic_dec_32(paoDestination); +} + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicExchangeAddNoResult(volatile atomicord32 *paoDestination, atomicord32 aoAddend) +{ + atomic_add_32(paoDestination, aoAddend); +} + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicAndNoResult(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + atomic_and_32(paoDestination, aoBitMask); +} + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicOrNoResult(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + atomic_or_32(paoDestination, aoBitMask); +} + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicXorNoResult(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + AtomicXor(paoDestination, aoBitMask); +} + + +#endif // #if _OU_TARGET_OS == _OU_TARGET_OS_SUNOS + + +////////////////////////////////////////////////////////////////////////// +// Generic UNIX implementation + +#if _OU_TARGET_OS == _OU_TARGET_OS_GENUNIX + +// No atomic functions for generic UNIX + +#if _OU_COMPILER == _OU_COMPILER_GCC && (_OU_TARGET_ARCH == _OU_TARGET_ARCH_X86 || _OU_TARGET_ARCH == _OU_TARGET_ARCH_X64) + +#define __OU_ATOMIC_X86_ASSEMBLER_USE_AUTOENABLED 1 + + +#endif // Otherwise the x86 assembler implementation must be engaged explicitly + + +#if _OU_ATOMIC_USE_X86_ASSEMBLER || (__OU_ATOMIC_X86_ASSEMBLER_USE_AUTOENABLED && !defined(_OU_ATOMIC_USE_X86_ASSEMBLER)) + +typedef uint32ou atomicord32; +typedef void *atomicptr; + + +struct _ou_atomic_CLargeStruct +{ + unsigned int m_uiData[32]; +}; + + +#define __OU_ATOMIC_ORD32_FUNCTIONS_DEFINED + + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicIncrement(volatile atomicord32 *paoDestination) +{ + atomicord32 aoResult = 1; + + asm volatile ( + "lock; xaddl %2, %0;" + : "=m" (*(volatile _ou_atomic_CLargeStruct *)paoDestination), "=r" (aoResult) + : "1" (aoResult), "m" (*paoDestination) + : "memory", "cc"); + + return aoResult + 1; +} + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicDecrement(volatile atomicord32 *paoDestination) +{ + atomicord32 aoResult = (atomicord32)(-1); + + asm volatile ( + "lock; xaddl %2, %0;" + : "=m" (*(volatile _ou_atomic_CLargeStruct *)paoDestination), "=r" (aoResult) + : "1" (aoResult), "m" (*paoDestination) + : "memory", "cc"); + + return aoResult - 1; +} + + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicExchange(volatile atomicord32 *paoDestination, atomicord32 aoExchange) +{ + atomicord32 aoResult; + + asm volatile ( + "xchgl %2, %0;" + : "=m" (*(volatile _ou_atomic_CLargeStruct *)paoDestination), "=r" (aoResult) + : "1" (aoExchange), "m" (*paoDestination) + : "memory"); + + return aoResult; +} + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicExchangeAdd(volatile atomicord32 *paoDestination, atomicord32 aoAddend) +{ + atomicord32 aoResult; + + asm volatile ( + "lock; xaddl %2, %0;" + : "=m" (*(volatile _ou_atomic_CLargeStruct *)paoDestination), "=r" (aoResult) + : "1" (aoAddend), "m" (*paoDestination) + : "memory", "cc"); + + return aoResult; +} + +static _OU_ALWAYSINLINE bool _OU_CONVENTION_API +/*bool */AtomicCompareExchange(volatile atomicord32 *paoDestination, atomicord32 aoComparand, atomicord32 aoExchange) +{ + bool bResult; + + asm volatile ( + "lock; cmpxchgl %3, %0;" + "setzb %1;" + : "=m" (*(volatile _ou_atomic_CLargeStruct *)paoDestination), "=a" (bResult) + : "a" (aoComparand), "r" (aoExchange), "m" (*paoDestination) + : "memory", "cc"); + + return bResult; +} + + +#define __OU_ATOMIC_BIT_FUNCTIONS_DEFINED + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicAnd(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + atomicord32 aoResult; + atomicord32 aoExchange; + + asm volatile ( + "0:;" + "movl %4, %2;" + "andl %3, %2;" + "lock; cmpxchgl %2, %0;" + "jnz 0b;" + : "=m" (*(volatile _ou_atomic_CLargeStruct *)paoDestination), "=a" (aoResult), "=&r" (aoExchange) + : "a" (*paoDestination), "g" (aoBitMask), "m" (*paoDestination) + : "memory", "cc"); + + return aoResult; +} + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicOr(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + atomicord32 aoResult; + atomicord32 aoExchange; + + asm volatile ( + "0:;" + "movl %4, %2;" + "orl %3, %2;" + "lock; cmpxchgl %2, %0;" + "jnz 0b;" + : "=m" (*(volatile _ou_atomic_CLargeStruct *)paoDestination), "=a" (aoResult), "=&r" (aoExchange) + : "a" (*paoDestination), "g" (aoBitMask), "m" (*paoDestination) + : "memory", "cc"); + + return aoResult; +} + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicXor(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + atomicord32 aoResult; + atomicord32 aoExchange; + + asm volatile ( + "0:;" + "movl %4, %2;" + "xorl %3, %2;" + "lock; cmpxchgl %2, %0;" + "jnz 0b;" + : "=m" (*(volatile _ou_atomic_CLargeStruct *)paoDestination), "=a" (aoResult), "=&r" (aoExchange) + : "a" (*paoDestination), "g" (aoBitMask), "m" (*paoDestination) + : "memory", "cc"); + + return aoResult; +} + + +#define __OU_ATOMIC_ORD32_NORESULT_FUNCTIONS_DEFINED + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicIncrementNoResult(volatile atomicord32 *paoDestination) +{ + asm volatile ( + "lock; incl %0;" + : "=m" (*(volatile _ou_atomic_CLargeStruct *)paoDestination) + : "m" (*paoDestination) + : "memory", "cc"); +} + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicDecrementNoResult(volatile atomicord32 *paoDestination) +{ + asm volatile ( + "lock; decl %0;" + : "=m" (*(volatile _ou_atomic_CLargeStruct *)paoDestination) + : "m" (*paoDestination) + : "memory", "cc"); +} + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicExchangeAddNoResult(volatile atomicord32 *paoDestination, atomicord32 aoAddend) +{ + asm volatile ( + "lock; addl %1, %0;" + : "=m,m,m" (*(volatile _ou_atomic_CLargeStruct *)paoDestination) + : "r,K,i" (aoAddend), "m,m,m" (*paoDestination) + : "memory", "cc"); +} + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicAndNoResult(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + asm volatile ( + "lock; andl %1, %0;" + : "=m,m,m" (*(volatile _ou_atomic_CLargeStruct *)paoDestination) + : "r,K,i" (aoBitMask), "m,m,m" (*paoDestination) + : "memory", "cc"); +} + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicOrNoResult(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + asm volatile ( + "lock; orl %1, %0;" + : "=m,m,m" (*(volatile _ou_atomic_CLargeStruct *)paoDestination) + : "r,K,i" (aoBitMask), "m,m,m" (*paoDestination) + : "memory", "cc"); +} + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicXorNoResult(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + asm volatile ( + "lock; xorl %1, %0;" + : "=m,m,m" (*(volatile _ou_atomic_CLargeStruct *)paoDestination) + : "r,K,i" (aoBitMask), "m,m,m" (*paoDestination) + : "memory", "cc"); +} + + +#define __OU_ATOMIC_PTR_FUNCTIONS_DEFINED + +static _OU_ALWAYSINLINE atomicptr _OU_CONVENTION_API +/*atomicptr */AtomicExchangePointer(volatile atomicptr *papDestination, atomicptr apExchange) +{ + atomicptr apResult; + + asm volatile ( + "xchg %2, %0;" + : "=m" (*(volatile _ou_atomic_CLargeStruct *)papDestination), "=r" (apResult) + : "1" (apExchange), "m" (*papDestination) + : "memory"); + + return apResult; +} + +static _OU_ALWAYSINLINE bool _OU_CONVENTION_API +/*bool */AtomicCompareExchangePointer(volatile atomicptr *papDestination, atomicptr apComparand, atomicptr apExchange) +{ + bool bResult; + + asm volatile ( + "lock; cmpxchg %3, %0;" + "setzb %1;" + : "=m" (*(volatile _ou_atomic_CLargeStruct *)papDestination), "=a" (bResult) + : "a" (apComparand), "r" (apExchange), "m" (*papDestination) + : "memory", "cc"); + + return bResult; +} + + +#endif // #if defined(_OU_ATOMIC_USE_X86_ASSEMBLER) + + +#endif // #if _OU_TARGET_OS == _OU_TARGET_OS_GENUNIX + + +////////////////////////////////////////////////////////////////////////// +// BitMask to CompareExchange forwarders + +#if defined(__OU_ATOMIC_ORD32_FUNCTIONS_DEFINED) && !defined(__OU_ATOMIC_BIT_FUNCTIONS_DEFINED) + +#define __OU_ATOMIC_BIT_FUNCTIONS_DEFINED + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicAnd(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + atomicord32 aoOldValue = *paoDestination; + + while (true) + { + if (AtomicCompareExchange(paoDestination, aoOldValue, (aoOldValue & aoBitMask))) + { + break; + } + + aoOldValue = *paoDestination; + } + + return aoOldValue; +} + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicOr(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + atomicord32 aoOldValue = *paoDestination; + + while (true) + { + if (AtomicCompareExchange(paoDestination, aoOldValue, (aoOldValue | aoBitMask))) + { + break; + } + + aoOldValue = *paoDestination; + } + + return aoOldValue; +} + +static _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_API +/*atomicord32 */AtomicXor(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + atomicord32 aoOldValue = *paoDestination; + + while (true) + { + if (AtomicCompareExchange(paoDestination, aoOldValue, (aoOldValue ^ aoBitMask))) + { + break; + } + + aoOldValue = *paoDestination; + } + + return aoOldValue; +} + + +#endif // #if defined(__OU_ATOMIC_ORD32_FUNCTIONS_DEFINED) && !defined(__OU_ATOMIC_BIT_FUNCTIONS_DEFINED) + + +////////////////////////////////////////////////////////////////////////// +// Pointer to ord32 forwarders + +#if defined(__OU_ATOMIC_ORD32_FUNCTIONS_DEFINED) && !defined(__OU_ATOMIC_PTR_FUNCTIONS_DEFINED) && _OU_TARGET_BITS == _OU_TARGET_BITS_32 + +#define __OU_ATOMIC_PTR_FUNCTIONS_DEFINED + +static _OU_ALWAYSINLINE atomicptr _OU_CONVENTION_API +/*atomicptr */AtomicExchangePointer(volatile atomicptr *papDestination, atomicptr apExchange) +{ + return (atomicptr)AtomicExchange((volatile atomicord32 *)papDestination, (atomicord32)apExchange); +} + +static _OU_ALWAYSINLINE bool _OU_CONVENTION_API +/*bool */AtomicCompareExchangePointer(volatile atomicptr *papDestination, atomicptr apComparand, atomicptr apExchange) +{ + return AtomicCompareExchange((volatile atomicord32 *)papDestination, (atomicord32)apComparand, (atomicord32)apExchange); +} + + +#endif // #if defined(__OU_ATOMIC_ORD32_FUNCTIONS_DEFINED) && !defined(__OU_ATOMIC_PTR_FUNCTIONS_DEFINED) && _OU_TARGET_BITS == _OU_TARGET_BITS_32 + + +////////////////////////////////////////////////////////////////////////// +// Atomic-via-mutex implementations + +#if !defined(__OU_ATOMIC_ORD32_FUNCTIONS_DEFINED) + + +END_NAMESPACE_OU(); + + +#include + + +BEGIN_NAMESPACE_OU(); + + +typedef uint32_t atomicord32; +typedef void *atomicptr; + + +atomicord32 _OU_CONVENTION_API AtomicIncrement(volatile atomicord32 *paoDestination); +atomicord32 _OU_CONVENTION_API AtomicDecrement(volatile atomicord32 *paoDestination); + +atomicord32 _OU_CONVENTION_API AtomicExchange(volatile atomicord32 *paoDestination, atomicord32 aoExchange); +atomicord32 _OU_CONVENTION_API AtomicExchangeAdd(volatile atomicord32 *paoDestination, atomicord32 aoAddend); +bool _OU_CONVENTION_API AtomicCompareExchange(volatile atomicord32 *paoDestination, atomicord32 aoComparand, atomicord32 aoExchange); + +atomicord32 _OU_CONVENTION_API AtomicAnd(volatile atomicord32 *paoDestination, atomicord32 aoBitMask); +atomicord32 _OU_CONVENTION_API AtomicOr(volatile atomicord32 *paoDestination, atomicord32 aoBitMask); +atomicord32 _OU_CONVENTION_API AtomicXor(volatile atomicord32 *paoDestination, atomicord32 aoBitMask); + + +#if defined(__OU_ATOMIC_BIT_FUNCTIONS_DEFINED) + +#error Internal error (__OU_ATOMIC_BIT_FUNCTIONS_DEFINED must not be defined in this case) + + +#endif // #if defined(__OU_ATOMIC_BIT_FUNCTIONS_DEFINED) + +#if defined(__OU_ATOMIC_PTR_FUNCTIONS_DEFINED) + +#error Internal error (__OU_ATOMIC_PTR_FUNCTIONS_DEFINED must not be defined in this case) + + +#endif // #if defined(__OU_ATOMIC_PTR_FUNCTIONS_DEFINED) + + +#endif // #if !defined(__OU_ATOMIC_ORD32_FUNCTIONS_DEFINED) + + +#if !defined(__OU_ATOMIC_PTR_FUNCTIONS_DEFINED) + +atomicptr _OU_CONVENTION_API AtomicExchangePointer(volatile atomicptr *papDestination, atomicptr apExchange); +bool _OU_CONVENTION_API AtomicCompareExchangePointer(volatile atomicptr *papDestination, atomicptr apComparand, atomicptr apExchange); + + +#if defined(__OU_DOXYGEN__) + +// Doxygen fooling declarations (used for documentation generation only) +void _OU_CONVENTION_API AtomicIncrementNoResult(volatile atomicord32 *paoDestination); +void _OU_CONVENTION_API AtomicDecrementNoResult(volatile atomicord32 *paoDestination); +void _OU_CONVENTION_API AtomicStore(volatile atomicord32 *paoDestination, atomicord32 aoValue); +void _OU_CONVENTION_API AtomicExchangeAddNoResult(volatile atomicord32 *paoDestination, atomicord32 aoAddend); +void _OU_CONVENTION_API AtomicAndNoResult(volatile atomicord32 *paoDestination, atomicord32 aoBitMask); +void _OU_CONVENTION_API AtomicOrNoResult(volatile atomicord32 *paoDestination, atomicord32 aoBitMask); +void _OU_CONVENTION_API AtomicXorNoResult(volatile atomicord32 *paoDestination, atomicord32 aoBitMask); +void _OU_CONVENTION_API AtomicStorePointer(volatile atomicptr *papDestination, atomicptr apValue); +void _OU_CONVENTION_API AtomicReadReorderBarrier(); + +#endif // #if defined(__OU_DOXYGEN__) + + +#define __OU_ATOMIC_OPERATIONS_VIA_MUTEXES +#define __OU_ATOMIC_INITIALIZATION_FUNCTIONS_REQUIRED + +// Initialization must be performed from main thread +bool _OU_CONVENTION_API InitializeAtomicAPI(); +void _OU_CONVENTION_API FinalizeAtomicAPI(); + + +#endif // #if !defined(__OU_ATOMIC_PTR_FUNCTIONS_DEFINED) + + +////////////////////////////////////////////////////////////////////////// +// No-result to result forwarders + +#if !defined(__OU_ATOMIC_ORD32_NORESULT_FUNCTIONS_DEFINED) + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicIncrementNoResult(volatile atomicord32 *paoDestination) +{ + AtomicIncrement(paoDestination); +} + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicDecrementNoResult(volatile atomicord32 *paoDestination) +{ + AtomicDecrement(paoDestination); +} + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicExchangeAddNoResult(volatile atomicord32 *paoDestination, atomicord32 aoAddend) +{ + AtomicExchangeAdd(paoDestination, aoAddend); +} + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicAndNoResult(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + AtomicAnd(paoDestination, aoBitMask); +} + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicOrNoResult(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + AtomicOr(paoDestination, aoBitMask); +} + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicXorNoResult(volatile atomicord32 *paoDestination, atomicord32 aoBitMask) +{ + AtomicXor(paoDestination, aoBitMask); +} + + +#endif // #if !defined(__OU_ATOMIC_ORD32_NORESULT_FUNCTIONS_DEFINED) + + +////////////////////////////////////////////////////////////////////////// +// Default Load/Store function implementations + +#if !defined(__OU_ATOMIC_READREORDERBARRIER_FUNCTION_DEFINED) && _OU_COMPILER == _OU_COMPILER_GCC + +// These architectures are known (by me ;-))to retain memory read request order +#if (_OU_TARGET_ARCH == _OU_TARGET_ARCH_X86 || _OU_TARGET_ARCH == _OU_TARGET_ARCH_X64) + +#define __OU_ATOMIC_READREORDERBARRIER_FUNCTION_DEFINED + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicReadReorderBarrier() +{ + // x86/x64 architectures do not reorder memory reads anyway + // it's only necessary to stop compiler from reordering read instructions + asm volatile ( "" : : :"memory" ); +} + + +#endif // #if (_OU_TARGET_ARCH == _OU_TARGET_ARCH_X86 || _OU_TARGET_ARCH == _OU_TARGET_ARCH_X64) + + +#endif // #if !defined(__OU_ATOMIC_READREORDERBARRIER_FUNCTION_DEFINED) && _OU_COMPILER == _OU_COMPILER_GCC + + +#ifndef __OU_ATOMIC_READREORDERBARRIER_FUNCTION_DEFINED + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicReadReorderBarrier() +{ + atomicord32 aoTemporaryValue; + AtomicExchangeAddNoResult(&aoTemporaryValue, 0); +} + + +#endif // #ifndef __OU_ATOMIC_READREORDERBARRIER_FUNCTION_DEFINED + + +#ifndef __OU_ATOMIC_STORE_FUNCTION_DEFINED + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicStore(volatile atomicord32 *paoDestination, atomicord32 aoValue) +{ + AtomicExchange(paoDestination, aoValue); +} + + +#endif // #ifndef __OU_ATOMIC_STORE_FUNCTION_DEFINED + + +#ifndef __OU_ATOMIC_STOREPTR_FUNCTION_DEFINED + +static _OU_ALWAYSINLINE void _OU_CONVENTION_API +/*void */AtomicStorePointer(volatile atomicptr *papDestination, atomicptr apValue) +{ + AtomicExchangePointer(papDestination, apValue); +} + + +#endif // #ifndef __OU_ATOMIC_STOREPTR_FUNCTION_DEFINED + + +////////////////////////////////////////////////////////////////////////// +// Atomic initialization function stubs + +#if !defined(__OU_ATOMIC_INITIALIZATION_FUNCTIONS_REQUIRED) + +// Initialization must be performed from main thread +static _OU_INLINE bool _OU_CONVENTION_API InitializeAtomicAPI() +{ + // Do nothing + + return true; +} + +static _OU_INLINE void _OU_CONVENTION_API FinalizeAtomicAPI() +{ + // Do nothing +} + + +#endif // #if !defined(__OU_ATOMIC_INITIALIZE_FUNCTIONS_DEFINED) + + +END_NAMESPACE_OU(); + + +#endif // #if _OU_FEATURE_SET >= _OU_FEATURE_SET_ATOMICS + + +#endif // #ifndef __OU_ATOMIC_H_INCLUDED diff --git a/libs/ode-0.16.1/ou/include/ou/atomicflags.h b/libs/ode-0.16.1/ou/include/ou/atomicflags.h new file mode 100644 index 0000000..58517fa --- /dev/null +++ b/libs/ode-0.16.1/ou/include/ou/atomicflags.h @@ -0,0 +1,367 @@ +/************************************************************************* + * * + * ODER's Utilities Library. Copyright (C) 2008-2019 Oleh Derevenko. * + * All rights reserved. e-mail: odar@eleks.com (change all "a" to "e") * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 3 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE-LESSER.TXT. Since LGPL is the extension of GPL * + * the text of GNU General Public License is also provided for * + * your information in file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * (3) The zlib/libpng license that is included with this library in * + * the file LICENSE-ZLIB.TXT * + * * + * This library is distributed WITHOUT ANY WARRANTY, including implied * + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * + * See the files LICENSE.TXT and LICENSE-LESSER.TXT or LICENSE-BSD.TXT * + * or LICENSE-ZLIB.TXT for more details. * + * * + *************************************************************************/ + +#ifndef __OU_ATOMICFLAGS_H_INCLUDED +#define __OU_ATOMICFLAGS_H_INCLUDED + + +#include +#include +#include +#include + + +BEGIN_NAMESPACE_OU(); + + +/* + * Implementation Note: + * Modification functions are implemented as memory barriers. + * Retrieval functions are implemented as ordinary memory accesses. + * Practice proves that such approach is quite sufficient to provide + * reliable synchronization mechanisms (provided a developer has solid + * knowledge in field, of course). + */ + +class CAtomicFlags +{ +public: + _OU_INLINE _OU_CONVENTION_METHOD CAtomicFlags(): + m_aoFlagsValue(0) + { + } + + _OU_INLINE _OU_CONVENTION_METHOD CAtomicFlags(atomicord32 aoFlagsValue): + m_aoFlagsValue(aoFlagsValue) + { + } + + typedef atomicord32 value_type; + +public: + _OU_ALWAYSINLINE void _OU_CONVENTION_METHOD + /*void */AssignFlagsAllValues(atomicord32 aoFlagsValue) + { + AtomicExchange(&m_aoFlagsValue, aoFlagsValue); + } + + _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_METHOD + /*atomicord32 */QueryFlagsAllValues() const + { + return m_aoFlagsValue; + } + + + // Can operate both on single flag and flag set + _OU_ALWAYSINLINE void _OU_CONVENTION_METHOD + /*void */SetFlagsMaskValue(atomicord32 aoFlagsMask, bool bFlagValue) + { + if (bFlagValue) + { + AtomicOrNoResult(&m_aoFlagsValue, aoFlagsMask); + } + else + { + AtomicAndNoResult(&m_aoFlagsValue, ~aoFlagsMask); + } + } + + // Can operate both on single flag and flag set + _OU_ALWAYSINLINE void _OU_CONVENTION_METHOD + /*void */SignalFlagsMaskValue(atomicord32 aoFlagsMask) + { + AtomicOrNoResult(&m_aoFlagsValue, aoFlagsMask); + } + + // Can operate both on single flag and flag set + _OU_ALWAYSINLINE void _OU_CONVENTION_METHOD + /*void */DropFlagsMaskValue(atomicord32 aoFlagsMask) + { + AtomicAndNoResult(&m_aoFlagsValue, ~aoFlagsMask); + } + + + // Can operate on single flag only + // Returns previous flag value + _OU_ALWAYSINLINE bool _OU_CONVENTION_METHOD + /*bool */ToggleSingleFlagValue(atomicord32 aoSingleFlag) + { + OU_ASSERT(OU_FLAGS_FLAG_IS_SINGLE(atomicord32, aoSingleFlag)); + + return (AtomicXor(&m_aoFlagsValue, aoSingleFlag) & aoSingleFlag) != (atomicord32)0; + } + + // Can operate on single flag only + // Returns if modification occurred + _OU_ALWAYSINLINE bool _OU_CONVENTION_METHOD + /*bool */ModifySingleFlagValue(atomicord32 aoSingleFlag, bool bFlagValue) + { + OU_ASSERT(OU_FLAGS_FLAG_IS_SINGLE(atomicord32, aoSingleFlag)); + + return bFlagValue + ? ((AtomicOr(&m_aoFlagsValue, aoSingleFlag) & aoSingleFlag) == (atomicord32)0) + : ((AtomicAnd(&m_aoFlagsValue, ~aoSingleFlag) & aoSingleFlag) != (atomicord32)0); + } + + + // Modifies subset of flags + // Returns previous flags + _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_METHOD + /*atomicord32 */AssignFlagsByMask(atomicord32 aoFlagsMask, atomicord32 aoFlagsValue) + { + atomicord32 aoFlagsOldValue; + + do + { + aoFlagsOldValue = m_aoFlagsValue; + } + while (!AtomicCompareExchange(&m_aoFlagsValue, aoFlagsOldValue, (aoFlagsOldValue & ~aoFlagsMask) | (aoFlagsValue & aoFlagsMask))); + + return aoFlagsOldValue; + } + + // Modifies subset of flags + // Returns if modification occurred + _OU_ALWAYSINLINE bool _OU_CONVENTION_METHOD + /*bool */AlterFlagsByMask(atomicord32 aoFlagsMask, atomicord32 aoFlagsValue) + { + atomicord32 aoFlagsOldValue; + + do + { + aoFlagsOldValue = m_aoFlagsValue; + } + while (!AtomicCompareExchange(&m_aoFlagsValue, aoFlagsOldValue, (aoFlagsOldValue & ~aoFlagsMask) | (aoFlagsValue & aoFlagsMask))); + + return ((aoFlagsOldValue ^ aoFlagsValue) & aoFlagsMask) != (atomicord32)0; + } + + + // Returns value of flag or tests for any bit in a mask + _OU_ALWAYSINLINE bool _OU_CONVENTION_METHOD + /*bool */GetFlagsMaskValue(atomicord32 aoFlagsMask) const + { + return (m_aoFlagsValue & aoFlagsMask) != (atomicord32)0; + } + + // Returns subset of flags + _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_METHOD + /*atomicord32 */QueryFlagsByMask(atomicord32 aoFlagsMask) const + { + return (m_aoFlagsValue & aoFlagsMask); + } + +public: + // Signal only flag out of mask + _OU_ALWAYSINLINE bool _OU_CONVENTION_METHOD + /*bool */OnlySignalSingleFlagOutOfMask(atomicord32 aoFlagsMask, atomicord32 aoSingleFlag) + { + OU_ASSERT(OU_FLAGS_FLAG_IS_SINGLE(atomicord32, aoSingleFlag)); + + bool bResult; + + atomicord32 aoFlagsOldValue; + + do + { + aoFlagsOldValue = m_aoFlagsValue; + + /* + * Implementation Note: + * 1) This function may be not a memory barrier. However that would also mean that + * no modification occurred and result is 'false'. Such behavior should be OK. + * 2) Even though second assignment to bResult is unnecessary it might yield + * better code as compiler does not need to save variable's value for the call + * to AtomicCompareExchange in this case. + */ + } + while ((bResult = !(aoFlagsOldValue & aoFlagsMask)) && !(bResult = AtomicCompareExchange(&m_aoFlagsValue, aoFlagsOldValue, aoFlagsOldValue | aoSingleFlag))); + + return bResult; + } + +public: + // Set value of flag indexed by enum + _OU_ALWAYSINLINE void _OU_CONVENTION_METHOD + /*void */EnumSetEnumeratedFlagValue(atomicord32 aoStartingFlag, unsigned int uiEnumeratedValue, unsigned int uiEnumeratedMaximum, bool bFlagValue) + { + OU_ASSERT(uiEnumeratedValue < uiEnumeratedMaximum && OU_FLAGS_ENUMFLAGS_START_VALID(atomicord32, aoStartingFlag, uiEnumeratedMaximum)); + + SetFlagsMaskValue(aoStartingFlag << uiEnumeratedValue, bFlagValue); + } + + // Signal value of flag indexed by enum + _OU_ALWAYSINLINE void _OU_CONVENTION_METHOD + /*void */EnumSignalEnumeratedFlagValue(atomicord32 aoStartingFlag, unsigned int uiEnumeratedValue, unsigned int uiEnumeratedMaximum) + { + OU_ASSERT(uiEnumeratedValue < uiEnumeratedMaximum && OU_FLAGS_ENUMFLAGS_START_VALID(atomicord32, aoStartingFlag, uiEnumeratedMaximum)); + + SignalFlagsMaskValue(aoStartingFlag << uiEnumeratedValue); + } + + // Drop value of flag indexed by enum + _OU_ALWAYSINLINE void _OU_CONVENTION_METHOD + /*void */EnumDropEnumeratedFlagValue(atomicord32 aoStartingFlag, unsigned int uiEnumeratedValue, unsigned int uiEnumeratedMaximum) + { + OU_ASSERT(uiEnumeratedValue < uiEnumeratedMaximum && OU_FLAGS_ENUMFLAGS_START_VALID(atomicord32, aoStartingFlag, uiEnumeratedMaximum)); + + DropFlagsMaskValue(aoStartingFlag << uiEnumeratedValue); + } + + + // Can operate on single flag only + // Returns previous flag value + _OU_ALWAYSINLINE bool _OU_CONVENTION_METHOD + /*bool */EnumToggleEnumeratedFlagValue(atomicord32 aoStartingFlag, unsigned int uiEnumeratedValue, unsigned int uiEnumeratedMaximum) + { + OU_ASSERT(uiEnumeratedValue < uiEnumeratedMaximum && OU_FLAGS_ENUMFLAGS_START_VALID(atomicord32, aoStartingFlag, uiEnumeratedMaximum)); + + return ToggleSingleFlagValue(aoStartingFlag << uiEnumeratedValue); + } + + // Can operate on single flag only + // Returns if modification occurred + _OU_ALWAYSINLINE bool _OU_CONVENTION_METHOD + /*bool */EnumModifyEnumeratedFlagValue(atomicord32 aoStartingFlag, unsigned int uiEnumeratedValue, unsigned int uiEnumeratedMaximum, bool bFlagValue) + { + OU_ASSERT(uiEnumeratedValue < uiEnumeratedMaximum && OU_FLAGS_ENUMFLAGS_START_VALID(atomicord32, aoStartingFlag, uiEnumeratedMaximum)); + + return ModifySingleFlagValue(aoStartingFlag << uiEnumeratedValue, bFlagValue); + } + + + // Returns if this was the first flag signaled + _OU_ALWAYSINLINE bool _OU_CONVENTION_METHOD + /*bool */EnumSignalFirstEnumeratedFlagValue(atomicord32 aoStartingFlag, unsigned int uiEnumeratedValue, unsigned int uiEnumeratedMaximum) + { + OU_ASSERT(uiEnumeratedValue < uiEnumeratedMaximum && OU_FLAGS_ENUMFLAGS_START_VALID(atomicord32, aoStartingFlag, uiEnumeratedMaximum)); + + return (AssignFlagsByMask(aoStartingFlag << uiEnumeratedValue, aoStartingFlag << uiEnumeratedValue) & OU_FLAGS_ENUMFLAGS_MASK(atomicord32, aoStartingFlag, uiEnumeratedMaximum)) == (atomicord32)0; + } + + // Returns if this was the last flag signaled + _OU_ALWAYSINLINE bool _OU_CONVENTION_METHOD + /*bool */EnumSignalLastEnumeratedFlagValue(atomicord32 aoStartingFlag, unsigned int uiEnumeratedValue, unsigned int uiEnumeratedMaximum) + { + OU_ASSERT(uiEnumeratedValue < uiEnumeratedMaximum && OU_FLAGS_ENUMFLAGS_START_VALID(atomicord32, aoStartingFlag, uiEnumeratedMaximum)); + + return (AssignFlagsByMask(aoStartingFlag << uiEnumeratedValue, aoStartingFlag << uiEnumeratedValue) & OU_FLAGS_ENUMFLAGS_MASK(atomicord32, aoStartingFlag, uiEnumeratedMaximum)) == (OU_FLAGS_ENUMFLAGS_MASK(atomicord32, aoStartingFlag, uiEnumeratedMaximum) & ~(aoStartingFlag << uiEnumeratedValue)); + } + + + // Retrieve value of flag indexed by enum + _OU_ALWAYSINLINE bool _OU_CONVENTION_METHOD + /*bool */EnumGetEnumeratedFlagValue(atomicord32 aoStartingFlag, unsigned int uiEnumeratedValue, unsigned int uiEnumeratedMaximum) const + { + OU_ASSERT(uiEnumeratedValue < uiEnumeratedMaximum && OU_FLAGS_ENUMFLAGS_START_VALID(atomicord32, aoStartingFlag, uiEnumeratedMaximum)); + + return GetFlagsMaskValue(aoStartingFlag << uiEnumeratedValue); + } + + // Find enum value for first flag signaled + _OU_INLINE int _OU_CONVENTION_METHOD + /*int */EnumFindFirstEnumeratedFlag(atomicord32 aoStartingFlag, unsigned int uiEnumeratedMaximum) const + { + OU_ASSERT(OU_FLAGS_ENUMFLAGS_START_VALID(atomicord32, aoStartingFlag, uiEnumeratedMaximum)); + + unsigned int uiResult = 0; + + atomicord32 aoFlagsMask = aoStartingFlag; + for (; uiResult < uiEnumeratedMaximum; ++uiResult, aoFlagsMask <<= 1) + { + if (GetFlagsMaskValue(aoFlagsMask)) + { + break; + } + } + + return uiResult; + } + +public: + // Signal all flags indexed by enum + _OU_ALWAYSINLINE void _OU_CONVENTION_METHOD + /*void */EnumAllSignalEnumeratedFlags(atomicord32 aoStartingFlag, unsigned int uiEnumeratedMaximum) + { + OU_ASSERT(OU_FLAGS_ENUMFLAGS_START_VALID(atomicord32, aoStartingFlag, uiEnumeratedMaximum)); + + SignalFlagsMaskValue(OU_FLAGS_ENUMFLAGS_MASK(atomicord32, aoStartingFlag, uiEnumeratedMaximum)); + } + + // Drop all flags indexed by enum + _OU_ALWAYSINLINE void _OU_CONVENTION_METHOD + /*void */EnumAllDropEnumeratedFlags(atomicord32 aoStartingFlag, unsigned int uiEnumeratedMaximum) + { + OU_ASSERT(OU_FLAGS_ENUMFLAGS_START_VALID(atomicord32, aoStartingFlag, uiEnumeratedMaximum)); + + DropFlagsMaskValue(OU_FLAGS_ENUMFLAGS_MASK(atomicord32, aoStartingFlag, uiEnumeratedMaximum)); + } + + + // Query all flags indexed by enum + _OU_ALWAYSINLINE atomicord32 _OU_CONVENTION_METHOD + /*atomicord32 */EnumAllQueryEnumeratedFlags(atomicord32 aoStartingFlag, unsigned int uiEnumeratedMaximum) const + { + OU_ASSERT(OU_FLAGS_ENUMFLAGS_START_VALID(atomicord32, aoStartingFlag, uiEnumeratedMaximum)); + + return QueryFlagsByMask(OU_FLAGS_ENUMFLAGS_MASK(atomicord32, aoStartingFlag, uiEnumeratedMaximum)); + } + + // Get if any flag indexed by enum is set + _OU_ALWAYSINLINE bool _OU_CONVENTION_METHOD + /*bool */EnumAnyGetEnumeratedFlagValue(atomicord32 aoStartingFlag, unsigned int uiEnumeratedMaximum) const + { + OU_ASSERT(OU_FLAGS_ENUMFLAGS_START_VALID(atomicord32, aoStartingFlag, uiEnumeratedMaximum)); + + return GetFlagsMaskValue(OU_FLAGS_ENUMFLAGS_MASK(atomicord32, aoStartingFlag, uiEnumeratedMaximum)); + } + +public: + // Store enumerated value in flags + _OU_ALWAYSINLINE void _OU_CONVENTION_METHOD + /*void */StoreFlagsEnumeratedValue(atomicord32 aoEnumeratedValueMask, unsigned int uiEnumeratedValueShift, unsigned int uiEnumeratedValue) + { + OU_ASSERT(OU_FLAGS_STOREENUM_VALUE_IN_MASK(atomicord32, uiEnumeratedValue, aoEnumeratedValueMask)); + + AssignFlagsByMask(aoEnumeratedValueMask << uiEnumeratedValueShift, (atomicord32)uiEnumeratedValue << uiEnumeratedValueShift); + } + + // Retrieve enumerated value from flags + _OU_ALWAYSINLINE unsigned int _OU_CONVENTION_METHOD + /*unsigned int */RetrieveFlagsEnumeratedValue(atomicord32 aoEnumeratedValueMask, unsigned int uiEnumeratedValueShift) const + { + return (unsigned int)((QueryFlagsAllValues() >> uiEnumeratedValueShift) & aoEnumeratedValueMask); + } + +private: + atomicord32 m_aoFlagsValue; +}; + + +END_NAMESPACE_OU(); + + +#endif // #ifndef __OU_ATOMICFLAGS_H_INCLUDED diff --git a/libs/ode-0.16.1/ou/include/ou/customization.h b/libs/ode-0.16.1/ou/include/ou/customization.h new file mode 100644 index 0000000..17fbeb0 --- /dev/null +++ b/libs/ode-0.16.1/ou/include/ou/customization.h @@ -0,0 +1,149 @@ +/************************************************************************* + * * + * ODER's Utilities Library. Copyright (C) 2008-2019 Oleh Derevenko. * + * All rights reserved. e-mail: odar@eleks.com (change all "a" to "e") * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 3 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE-LESSER.TXT. Since LGPL is the extension of GPL * + * the text of GNU General Public License is also provided for * + * your information in file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * (3) The zlib/libpng license that is included with this library in * + * the file LICENSE-ZLIB.TXT * + * * + * This library is distributed WITHOUT ANY WARRANTY, including implied * + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * + * See the files LICENSE.TXT and LICENSE-LESSER.TXT or LICENSE-BSD.TXT * + * or LICENSE-ZLIB.TXT for more details. * + * * + *************************************************************************/ + +#ifndef __OU_CUSTOMIZATION_H_INCLUDED +#define __OU_CUSTOMIZATION_H_INCLUDED + + +#include +#include +#include + +#include + + +BEGIN_NAMESPACE_OU(); + + +////////////////////////////////////////////////////////////////////////// +// Some helper definitions for assert macros + +#if !defined(__FILE__) + +// Definition of __FILE__ constant for the case if compiler does not support the macro +extern const char *const __FILE__; + + +#endif // #if !defined(__FILE__) + + +#if !defined(__LINE__) + +// Definition of __LINE__ constant for the case if compiler does not support the macro +extern const unsigned int __LINE__; + + +#endif // #if !defined(__LINE__) + + +////////////////////////////////////////////////////////////////////////// +// Assertion checks customization + +enum EASSERTIONFAILURESEVERITY +{ + AFS__MIN, + + AFS_ASSERT = AFS__MIN, + AFS_CHECK, + + AFS__MAX, +}; + + +typedef void (_OU_CONVENTION_CALLBACK *CAssertionFailedProcedure)(EASSERTIONFAILURESEVERITY fsFailureSeverity, + const char *szAssertionExpression, const char *szAssertionFileName, unsigned int uiAssertionSourceLine); + + +class CAssertionCheckCustomization +{ +public: + static _OU_ALWAYSINLINE CAssertionFailedProcedure _OU_CONVENTION_API + /*CAssertionFailedProcedure */GetAssertFailureCustomHandler() + { + return g_fnAssertFailureHandler; + } + + static _OU_INLINE void _OU_CONVENTION_API CustomizeAssertionChecks(CAssertionFailedProcedure fnAssertionFailureProcedure) + { + g_fnAssertFailureHandler = fnAssertionFailureProcedure; + } + +private: + static CAssertionFailedProcedure g_fnAssertFailureHandler; +}; + + +////////////////////////////////////////////////////////////////////////// +// Memory manager customization + +#define _OU_MEMORY_REQUIRED_ALIGNMENT sizeof(_OU_NAMESPACE::uint64ou) + + +typedef void *(_OU_CONVENTION_CALLBACK *CMemoryAllocationProcedure)(size_t nBlockSize); +typedef void *(_OU_CONVENTION_CALLBACK *CMemoryReallocationProcedure)(void *pv_ExistingBlock, size_t nBlockNewSize); +typedef void (_OU_CONVENTION_CALLBACK *CMemoryDeallocationProcedure)(void *pv_ExistingBlock); + + +class CMemoryManagerCustomization +{ +public: + static _OU_ALWAYSINLINE CMemoryAllocationProcedure _OU_CONVENTION_API + /*CMemoryAllocationProcedure */GetMemoryAllocationCustomProcedure() + { + return g_fnMemoryAllocationProcedure; + } + + static _OU_ALWAYSINLINE CMemoryReallocationProcedure _OU_CONVENTION_API + /*CMemoryReallocationProcedure */GetMemoryReallocationCustomProcedure() + { + return g_fnMemoryReallocationProcedure; + } + + static _OU_ALWAYSINLINE CMemoryDeallocationProcedure _OU_CONVENTION_API + /*CMemoryDeallocationProcedure */GetMemoryDeallocationCustomProcedure() + { + return g_fnMemoryDeallocationProcedure; + } + + static _OU_INLINE void _OU_CONVENTION_API CustomizeMemoryManager(CMemoryAllocationProcedure fnAllocationProcedure, + CMemoryReallocationProcedure fnReallocationProcedure, CMemoryDeallocationProcedure fnDeallocationProcedure) + { + g_fnMemoryAllocationProcedure = fnAllocationProcedure; + g_fnMemoryReallocationProcedure = fnReallocationProcedure; + g_fnMemoryDeallocationProcedure = fnDeallocationProcedure; + } + +private: + static CMemoryAllocationProcedure g_fnMemoryAllocationProcedure; + static CMemoryReallocationProcedure g_fnMemoryReallocationProcedure; + static CMemoryDeallocationProcedure g_fnMemoryDeallocationProcedure; +}; + + +END_NAMESPACE_OU(); + + +#endif // #ifndef __OU_CUSTOMIZATION_H_INCLUDED diff --git a/libs/ode-0.16.1/ou/include/ou/enumarrays.h b/libs/ode-0.16.1/ou/include/ou/enumarrays.h new file mode 100644 index 0000000..d8ce0c1 --- /dev/null +++ b/libs/ode-0.16.1/ou/include/ou/enumarrays.h @@ -0,0 +1,256 @@ +/************************************************************************* + * * + * ODER's Utilities Library. Copyright (C) 2008-2019 Oleh Derevenko. * + * All rights reserved. e-mail: odar@eleks.com (change all "a" to "e") * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 3 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE-LESSER.TXT. Since LGPL is the extension of GPL * + * the text of GNU General Public License is also provided for * + * your information in file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * (3) The zlib/libpng license that is included with this library in * + * the file LICENSE-ZLIB.TXT * + * * + * This library is distributed WITHOUT ANY WARRANTY, including implied * + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * + * See the files LICENSE.TXT and LICENSE-LESSER.TXT or LICENSE-BSD.TXT * + * or LICENSE-ZLIB.TXT for more details. * + * * + *************************************************************************/ + +#ifndef __OU_ENUMARRAYS_H_INCLUDED +#define __OU_ENUMARRAYS_H_INCLUDED + + +#include +#include +#include +#include + + +BEGIN_NAMESPACE_OU(); + + +////////////////////////////////////////////////////////////////////////// +// Helper template definitions + +template +struct CTypeStandardEqual +{ + _OU_INLINE bool _OU_CONVENTION_METHOD operator ()(const ElementType &etLeftElement, const ElementType &etRightElement) const + { + return etLeftElement == etRightElement; + } +}; + +template +struct CTypeStandardLess +{ + _OU_INLINE bool _OU_CONVENTION_METHOD operator ()(const ElementType &etLeftElement, const ElementType &etRightElement) const + { + return etLeftElement < etRightElement; + } +}; + + +////////////////////////////////////////////////////////////////////////// +// CEnumUnsortedElementArray definition + +/* + * Implementation Note: + * The array is intended to store static constant data. + * Therefore CElementEqualType should not ever need a nontrivial constructor + * and it is acceptable to have it as template parameter. + */ + +template > +class CEnumUnsortedElementArray +{ +public: + _OU_CONVENTION_METHOD CEnumUnsortedElementArray() + { +#if !defined(NDEBUG) + +#if _OU_COMPILER != _OU_COMPILER_GCC || _OU_COMPILER_VERSION == _OU_COMPILER_VERSION_GCCLT4 + + OU_ASSERT(OU_ARRAY_SIZE(m_aetElementArray) == EnumMax); + + +#endif // #if _OU_COMPILER != _OU_COMPILER_GCC || _OU_COMPILER_VERSION == _OU_COMPILER_VERSION_GCCLT4 + + +#endif // #if !defined(NDEBUG) + } + +public: + static _OU_ALWAYSINLINE const EnumType _OU_CONVENTION_API + /*const EnumType */Decode(const ElementType &etValue) + { + const ElementType *itElementFound = FindValueSequentially(m_aetElementArray, m_aetElementArray + EnumMax, etValue); + + EnumType etResult = (EnumType)(itElementFound - m_aetElementArray); + return etResult; + } + + static _OU_ALWAYSINLINE const ElementType &_OU_CONVENTION_API + /*const ElementType &*/Encode(const EnumType &etValue) + { + OU_ASSERT(sizeof(EnumType) <= sizeof(int)); + OU_ASSERT(OU_IN_INT_RANGE(etValue, 0, EnumMax)); + + return m_aetElementArray[etValue]; + } + + static _OU_ALWAYSINLINE bool _OU_CONVENTION_API + /*bool */IsValidDecode(const EnumType &etValue) + { + return etValue != EnumMax; + } + + static _OU_ALWAYSINLINE const ElementType *_OU_CONVENTION_API + /*const ElementType **/GetStoragePointer() + { + return m_aetElementArray; + } + +private: + static const ElementType *_OU_CONVENTION_API FindValueSequentially(const ElementType *petArrayBegin, const ElementType *petArrayEnd, const ElementType &etValue) + { + const CElementEqualType etElementEqual = CElementEqualType(); + + const ElementType *petCurrentElement = petArrayBegin; + + for (; petCurrentElement != petArrayEnd; ++petCurrentElement) + { + if (etElementEqual(*petCurrentElement, etValue)) + { + break; + } + } + + return petCurrentElement; + } + +private: + static const ElementType m_aetElementArray[]; +}; + + +////////////////////////////////////////////////////////////////////////// +// CEnumSortedElementArray definition + +/* + * Implementation Note: + * The array is intended to store static constant data. + * Therefore CElementLessType and CElementEqualType should not ever need + * a nontrivial constructor and it is acceptable to have them + * as template parameters. + */ + +template > +class CEnumSortedElementArray +{ +public: + _OU_INLINE _OU_CONVENTION_METHOD CEnumSortedElementArray() + { +#if !defined(NDEBUG) + +#if _OU_COMPILER != _OU_COMPILER_GCC || _OU_COMPILER_VERSION == _OU_COMPILER_VERSION_GCCLT4 + + OU_ASSERT(OU_ARRAY_SIZE(m_aetElementArray) == EnumMax); + + +#endif // #if _OU_COMPILER != _OU_COMPILER_GCC || _OU_COMPILER_VERSION == _OU_COMPILER_VERSION_GCCLT4 + + const CElementLessType ltElementLess = CElementLessType(); + + for (unsigned nElementIndex = 1; nElementIndex < EnumMax; ++nElementIndex) + { + OU_ASSERT(ltElementLess(m_aetElementArray[nElementIndex - 1], m_aetElementArray[nElementIndex])); // Element values must be sorted + } + + +#endif // #if !defined(NDEBUG) + } + + static _OU_ALWAYSINLINE const EnumType _OU_CONVENTION_API + /*const EnumType */Decode(const ElementType &etValue) + { + const CElementLessType ltElementLess = CElementLessType(); + + EnumType etResult = EnumMax; + + const ElementType *itElementFound = FindValueLowerBound(m_aetElementArray, m_aetElementArray + EnumMax, etValue); + + if (itElementFound != m_aetElementArray + EnumMax) + { + if (!ltElementLess(etValue, *itElementFound)) + { + etResult = (EnumType)(itElementFound - m_aetElementArray); + } + } + + return etResult; + } + + static _OU_ALWAYSINLINE const ElementType &_OU_CONVENTION_API + /*const ElementType &*/Encode(const EnumType &etValue) + { + OU_ASSERT(sizeof(EnumType) <= sizeof(int)); + OU_ASSERT(OU_IN_INT_RANGE(etValue, 0, EnumMax)); + + return m_aetElementArray[etValue]; + } + + static _OU_ALWAYSINLINE bool _OU_CONVENTION_API + /*bool */IsValidDecode(const EnumType &etValue) + { + return etValue != EnumMax; + } + + static _OU_ALWAYSINLINE const ElementType *_OU_CONVENTION_API + /*const ElementType **/GetStoragePointer() + { + return m_aetElementArray; + } + +private: + static const ElementType *_OU_CONVENTION_API FindValueLowerBound(const ElementType *petArrayBegin, const ElementType *petArrayEnd, const ElementType &etValue) + { + const CElementLessType ltElementLess = CElementLessType(); + + const ElementType *petCurrentRangeBegin = petArrayBegin; + const ElementType *petCurrentRangeEnd = petArrayEnd; + + while (petCurrentRangeBegin != petCurrentRangeEnd) + { + const ElementType *petCurrentRangeMiddle = petCurrentRangeBegin + (petCurrentRangeEnd - petCurrentRangeBegin) / 2; + + if (ltElementLess(*petCurrentRangeMiddle, etValue)) + { + petCurrentRangeBegin = petCurrentRangeMiddle + 1; + } + else + { + petCurrentRangeEnd = petCurrentRangeMiddle; + } + } + + return petCurrentRangeBegin; + } + +private: + static const ElementType m_aetElementArray[]; +}; + + +END_NAMESPACE_OU(); + + +#endif // #ifndef __OU_ENUMARRAYS_H_INCLUDED diff --git a/libs/ode-0.16.1/ou/include/ou/features.h b/libs/ode-0.16.1/ou/include/ou/features.h new file mode 100644 index 0000000..bf50a57 --- /dev/null +++ b/libs/ode-0.16.1/ou/include/ou/features.h @@ -0,0 +1,51 @@ +/************************************************************************* + * * + * ODER's Utilities Library. Copyright (C) 2008-2019 Oleh Derevenko. * + * All rights reserved. e-mail: odar@eleks.com (change all "a" to "e") * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 3 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE-LESSER.TXT. Since LGPL is the extension of GPL * + * the text of GNU General Public License is also provided for * + * your information in file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * (3) The zlib/libpng license that is included with this library in * + * the file LICENSE-ZLIB.TXT * + * * + * This library is distributed WITHOUT ANY WARRANTY, including implied * + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * + * See the files LICENSE.TXT and LICENSE-LESSER.TXT or LICENSE-BSD.TXT * + * or LICENSE-ZLIB.TXT for more details. * + * * + *************************************************************************/ + +#ifndef __OU_FEATURES_H_INCLUDED +#define __OU_FEATURES_H_INCLUDED + + +////////////////////////////////////////////////////////////////////////// +// Feature set definitions + +#define _OU_FEATURE_SET_BASICS 0 +#define _OU_FEATURE_SET_ATOMICS 1 +#define _OU_FEATURE_SET_TLS 2 + +#define _OU_FEATURE_SET__MAX 3 + + +////////////////////////////////////////////////////////////////////////// + +#if !defined(_OU_FEATURE_SET) + +#define _OU_FEATURE_SET _OU_FEATURE_SET__MAX + + +#endif // #if !defined(_OU_FEATURE_SET) + + +#endif // #ifndef __OU_FEATURES_H_INCLUDED diff --git a/libs/ode-0.16.1/ou/include/ou/flags.h b/libs/ode-0.16.1/ou/include/ou/flags.h new file mode 100644 index 0000000..781dd6b --- /dev/null +++ b/libs/ode-0.16.1/ou/include/ou/flags.h @@ -0,0 +1,35 @@ +/************************************************************************* + * * + * ODER's Utilities Library. Copyright (C) 2008-2019 Oleh Derevenko. * + * All rights reserved. e-mail: odar@eleks.com (change all "a" to "e") * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 3 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE-LESSER.TXT. Since LGPL is the extension of GPL * + * the text of GNU General Public License is also provided for * + * your information in file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * (3) The zlib/libpng license that is included with this library in * + * the file LICENSE-ZLIB.TXT * + * * + * This library is distributed WITHOUT ANY WARRANTY, including implied * + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * + * See the files LICENSE.TXT and LICENSE-LESSER.TXT or LICENSE-BSD.TXT * + * or LICENSE-ZLIB.TXT for more details. * + * * + *************************************************************************/ + +#ifndef __OU_FLAGS_H_INCLUDED +#define __OU_FLAGS_H_INCLUDED + + +#include +#include + + +#endif // #ifndef __OU_FLAGS_H_INCLUDED diff --git a/libs/ode-0.16.1/ou/include/ou/flagsdefines.h b/libs/ode-0.16.1/ou/include/ou/flagsdefines.h new file mode 100644 index 0000000..b294ead --- /dev/null +++ b/libs/ode-0.16.1/ou/include/ou/flagsdefines.h @@ -0,0 +1,37 @@ +/************************************************************************* + * * + * ODER's Utilities Library. Copyright (C) 2008-2019 Oleh Derevenko. * + * All rights reserved. e-mail: odar@eleks.com (change all "a" to "e") * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 3 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE-LESSER.TXT. Since LGPL is the extension of GPL * + * the text of GNU General Public License is also provided for * + * your information in file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * (3) The zlib/libpng license that is included with this library in * + * the file LICENSE-ZLIB.TXT * + * * + * This library is distributed WITHOUT ANY WARRANTY, including implied * + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * + * See the files LICENSE.TXT and LICENSE-LESSER.TXT or LICENSE-BSD.TXT * + * or LICENSE-ZLIB.TXT for more details. * + * * + *************************************************************************/ + +#ifndef __OU_FLAGSDEFINES_H_INCLUDED +#define __OU_FLAGSDEFINES_H_INCLUDED + + +#define OU_FLAGS_ENUMFLAGS_MASK(Type, StartingFlag, EnumMax) ((Type)((Type)((Type)((Type)(StartingFlag) << ((EnumMax) - 1)) - (Type)(StartingFlag)) | (Type)((Type)(StartingFlag) << ((EnumMax) - 1)))) +#define OU_FLAGS_ENUMFLAGS_START_VALID(Type, StartingFlag, EnumMax) ((Type)((Type)(StartingFlag) << ((EnumMax) - 1)) != 0) +#define OU_FLAGS_STOREENUM_VALUE_IN_MASK(Type, EnumValue, ValueMask) ((Type)(ValueMask) != 0 && ((Type)(EnumValue) & (Type)(~((Type)(ValueMask)))) == 0) +#define OU_FLAGS_FLAG_IS_SINGLE(Type, Flag) ((Type)(Flag) != 0 && ((Type)(Flag) & (Type)((Type)(Flag) - (Type)1)) == 0) + + +#endif // #ifndef __OU_FLAGSDEFINES_H_INCLUDED diff --git a/libs/ode-0.16.1/ou/include/ou/inttypes.h b/libs/ode-0.16.1/ou/include/ou/inttypes.h new file mode 100644 index 0000000..b69b622 --- /dev/null +++ b/libs/ode-0.16.1/ou/include/ou/inttypes.h @@ -0,0 +1,136 @@ +/************************************************************************* + * * + * ODER's Utilities Library. Copyright (C) 2008-2019 Oleh Derevenko. * + * All rights reserved. e-mail: odar@eleks.com (change all "a" to "e") * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 3 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE-LESSER.TXT. Since LGPL is the extension of GPL * + * the text of GNU General Public License is also provided for * + * your information in file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * (3) The zlib/libpng license that is included with this library in * + * the file LICENSE-ZLIB.TXT * + * * + * This library is distributed WITHOUT ANY WARRANTY, including implied * + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * + * See the files LICENSE.TXT and LICENSE-LESSER.TXT or LICENSE-BSD.TXT * + * or LICENSE-ZLIB.TXT for more details. * + * * + *************************************************************************/ + +#ifndef __OU_INTTYPES_H_INCLUDED +#define __OU_INTTYPES_H_INCLUDED + + +#include +#include + + +BEGIN_NAMESPACE_OU(); + +/* + * Implementation Note: + * Standard [u]int??_t type names are avoided to prevent possibility + * of conflict with system types which might be the preprocessor defines. + * If you know that all your target platforms do not use defines for + * integer types, you can typedef them to convenient names after inclusion + * of "ou" library. + */ + + +#if _OU_COMPILER == _OU_COMPILER_MSVC + +typedef __int8 int8ou; +typedef unsigned __int8 uint8ou; + +typedef __int16 int16ou; +typedef unsigned __int16 uint16ou; + +typedef __int32 int32ou; +typedef unsigned __int32 uint32ou; + +typedef __int64 int64ou; +typedef unsigned __int64 uint64ou; + + +#else // #if _OU_TARGET_OS != _OU_TARGET_OS_WINDOWS + + +END_NAMESPACE_OU(); + + +#include + +typedef int8_t __ou_global_int8; +typedef uint8_t __ou_global_uint8; + +typedef int16_t __ou_global_int16; +typedef uint16_t __ou_global_uint16; + +typedef int32_t __ou_global_int32; +typedef uint32_t __ou_global_uint32; + +typedef int64_t __ou_global_int64; +typedef uint64_t __ou_global_uint64; + + +BEGIN_NAMESPACE_OU(); + + +typedef ::__ou_global_int8 int8ou; +typedef ::__ou_global_uint8 uint8ou; + +typedef ::__ou_global_int16 int16ou; +typedef ::__ou_global_uint16 uint16ou; + +typedef ::__ou_global_int32 int32ou; +typedef ::__ou_global_uint32 uint32ou; + +typedef ::__ou_global_int64 int64ou; +typedef ::__ou_global_uint64 uint64ou; + + +#endif // #if _OU_TARGET_OS == ... + + +#define OU_BITS_IN_BYTE 8U + +#define OU_UINT8_BITS (sizeof(_OU_NAMESPACE::uint8ou) * OU_BITS_IN_BYTE) +#define OU_INT8_BITS (sizeof(_OU_NAMESPACE::int8ou) * OU_BITS_IN_BYTE) +#define OU_UINT8_MAX ((_OU_NAMESPACE::uint8ou)(-1)) +#define OU_UINT8_MIN ((_OU_NAMESPACE::uint8ou)0) +#define OU_INT8_MAX ((_OU_NAMESPACE::int8ou)(OU_UINT8_MAX >> 1)) +#define OU_INT8_MIN ((_OU_NAMESPACE::int8ou)(OU_UINT8_MAX - OU_INT8_MAX)) + +#define OU_UINT16_BITS (sizeof(_OU_NAMESPACE::uint16ou) * OU_BITS_IN_BYTE) +#define OU_INT16_BITS (sizeof(_OU_NAMESPACE::int16ou) * OU_BITS_IN_BYTE) +#define OU_UINT16_MAX ((_OU_NAMESPACE::uint16ou)(-1)) +#define OU_UINT16_MIN ((_OU_NAMESPACE::uint16ou)0) +#define OU_INT16_MAX ((_OU_NAMESPACE::int16ou)(OU_UINT16_MAX >> 1)) +#define OU_INT16_MIN ((_OU_NAMESPACE::int16ou)(OU_UINT16_MAX - OU_INT16_MAX)) + +#define OU_UINT32_BITS (sizeof(_OU_NAMESPACE::uint32ou) * OU_BITS_IN_BYTE) +#define OU_INT32_BITS (sizeof(_OU_NAMESPACE::int32ou) * OU_BITS_IN_BYTE) +#define OU_UINT32_MAX ((_OU_NAMESPACE::uint32ou)(-1)) +#define OU_UINT32_MIN ((_OU_NAMESPACE::uint32ou)0) +#define OU_INT32_MAX ((_OU_NAMESPACE::int32ou)(OU_UINT32_MAX >> 1)) +#define OU_INT32_MIN ((_OU_NAMESPACE::int32ou)(OU_UINT32_MAX - OU_INT32_MAX)) + +#define OU_UINT64_BITS (sizeof(_OU_NAMESPACE::uint64ou) * OU_BITS_IN_BYTE) +#define OU_INT64_BITS (sizeof(_OU_NAMESPACE::int64ou) * OU_BITS_IN_BYTE) +#define OU_UINT64_MAX ((_OU_NAMESPACE::uint64ou)(-1)) +#define OU_UINT64_MIN ((_OU_NAMESPACE::uint64ou)0) +#define OU_INT64_MAX ((_OU_NAMESPACE::int64ou)(OU_UINT64_MAX >> 1)) +#define OU_INT64_MIN ((_OU_NAMESPACE::int64ou)(OU_UINT64_MAX - OU_INT64_MAX)) + + +END_NAMESPACE_OU(); + + +#endif // #ifndef __OU_INTTYPES_H_INCLUDED diff --git a/libs/ode-0.16.1/ou/include/ou/macros.h b/libs/ode-0.16.1/ou/include/ou/macros.h new file mode 100644 index 0000000..bfbf5d7 --- /dev/null +++ b/libs/ode-0.16.1/ou/include/ou/macros.h @@ -0,0 +1,79 @@ +/************************************************************************* + * * + * ODER's Utilities Library. Copyright (C) 2008-2019 Oleh Derevenko. * + * All rights reserved. e-mail: odar@eleks.com (change all "a" to "e") * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 3 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE-LESSER.TXT. Since LGPL is the extension of GPL * + * the text of GNU General Public License is also provided for * + * your information in file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * (3) The zlib/libpng license that is included with this library in * + * the file LICENSE-ZLIB.TXT * + * * + * This library is distributed WITHOUT ANY WARRANTY, including implied * + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * + * See the files LICENSE.TXT and LICENSE-LESSER.TXT or LICENSE-BSD.TXT * + * or LICENSE-ZLIB.TXT for more details. * + * * + *************************************************************************/ + +#ifndef __OU_MACROS_H_INCLUDED +#define __OU_MACROS_H_INCLUDED + + +#include + + +////////////////////////////////////////////////////////////////////////// +// offsetof macro redefinition for QNX (to avoid compiler warning) + +#if _OU_TARGET_OS == _OU_TARGET_OS_QNX + + +#undef offsetof +#define offsetof(s, m) ((size_t)&(((s *)8)->m) - (size_t)8) + + +#endif // #if _OU_TARGET_OS == _OU_TARGET_OS_QNX + + +////////////////////////////////////////////////////////////////////////// +// OU_ALIGNED_SIZE macro + +#define OU_ALIGNED_SIZET(Size, Alignment) (((size_t)(Size) + (size_t)((Alignment) - 1)) & ~((size_t)((Alignment) - 1))) +#define OU_ALIGNED_INT(Size, Alignment) (((unsigned int)(Size) + (unsigned int)((Alignment) - 1)) & ~((unsigned int)((Alignment) - 1))) + +#define OU_ALIGNED_SIZE(Size, Alignment) OU_ALIGNED_SIZET(Size, Alignment) + + +////////////////////////////////////////////////////////////////////////// +// OU_ARRAY_SIZE macro + +#define OU_ARRAY_SIZE(Array) (sizeof(Array) / sizeof((Array)[0])) + + +////////////////////////////////////////////////////////////////////////// +// OU_IN_*_RANGE macros + +/* + * Implementation Note: + * It seems to me "unsigned long long" is not always available. + * Therefore I find _OU_NAMESPACE::uint64ou a more safe choice. + * You have to include for it to work. + * I do not include the header automaticaly to keep + * a low-level header. + */ + +#define OU_IN_INT_RANGE(Value, Min, Max) ((unsigned int)((unsigned int)(Value) - (unsigned int)(Min)) < (unsigned int)((unsigned int)(Max) - (unsigned int)(Min))) +#define OU_IN_I64_RANGE(Value, Min, Max) ((_OU_NAMESPACE::uint64ou)((_OU_NAMESPACE::uint64ou)(Value) - (_OU_NAMESPACE::uint64ou)(Min)) < (_OU_NAMESPACE::uint64ou)((_OU_NAMESPACE::uint64ou)(Max) - (_OU_NAMESPACE::uint64ou)(Min))) +#define OU_IN_SIZET_RANGE(Value, Min, Max) ((size_t)((size_t)(Value) - (size_t)(Min)) < (size_t)((size_t)(Max) - (size_t)(Min))) + + +#endif // #ifndef __OU_MACROS_H_INCLUDED diff --git a/libs/ode-0.16.1/ou/include/ou/malloc.h b/libs/ode-0.16.1/ou/include/ou/malloc.h new file mode 100644 index 0000000..9a758c5 --- /dev/null +++ b/libs/ode-0.16.1/ou/include/ou/malloc.h @@ -0,0 +1,48 @@ +/************************************************************************* + * * + * ODER's Utilities Library. Copyright (C) 2008-2019 Oleh Derevenko. * + * All rights reserved. e-mail: odar@eleks.com (change all "a" to "e") * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 3 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE-LESSER.TXT. Since LGPL is the extension of GPL * + * the text of GNU General Public License is also provided for * + * your information in file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * (3) The zlib/libpng license that is included with this library in * + * the file LICENSE-ZLIB.TXT * + * * + * This library is distributed WITHOUT ANY WARRANTY, including implied * + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * + * See the files LICENSE.TXT and LICENSE-LESSER.TXT or LICENSE-BSD.TXT * + * or LICENSE-ZLIB.TXT for more details. * + * * + *************************************************************************/ + +#ifndef __OU_MALLOC_H_INCLUDED +#define __OU_MALLOC_H_INCLUDED + + +#include +#include + +#include + + +BEGIN_NAMESPACE_OU(); + + +void *_OU_CONVENTION_API AllocateMemoryBlock(size_t nBlockSize); +void *_OU_CONVENTION_API ReallocateMemoryBlock(void *pv_ExistingBlock, size_t nNewBlockSize); +void _OU_CONVENTION_API FreeMemoryBlock(void *pv_ExistingBlock); + + +END_NAMESPACE_OU(); + + +#endif // #ifndef __OU_MALLOC_H_INCLUDED diff --git a/libs/ode-0.16.1/ou/include/ou/namespace.h b/libs/ode-0.16.1/ou/include/ou/namespace.h new file mode 100644 index 0000000..3b57ab1 --- /dev/null +++ b/libs/ode-0.16.1/ou/include/ou/namespace.h @@ -0,0 +1,43 @@ +/************************************************************************* + * * + * ODER's Utilities Library. Copyright (C) 2008-2019 Oleh Derevenko. * + * All rights reserved. e-mail: odar@eleks.com (change all "a" to "e") * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 3 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE-LESSER.TXT. Since LGPL is the extension of GPL * + * the text of GNU General Public License is also provided for * + * your information in file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * (3) The zlib/libpng license that is included with this library in * + * the file LICENSE-ZLIB.TXT * + * * + * This library is distributed WITHOUT ANY WARRANTY, including implied * + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * + * See the files LICENSE.TXT and LICENSE-LESSER.TXT or LICENSE-BSD.TXT * + * or LICENSE-ZLIB.TXT for more details. * + * * + *************************************************************************/ + +#ifndef __OU_NAMESPACE_H_INCLUDED +#define __OU_NAMESPACE_H_INCLUDED + + +#ifndef _OU_NAMESPACE + +#define _OU_NAMESPACE ou + + +#endif // #ifndef _OU_NAMESPACE + + +#define BEGIN_NAMESPACE_OU() namespace _OU_NAMESPACE { +#define END_NAMESPACE_OU() } /* namespace _OU_NAMESPACE */ + + +#endif // #ifndef __OU_NAMESPACE_H_INCLUDED diff --git a/libs/ode-0.16.1/ou/include/ou/platform.h b/libs/ode-0.16.1/ou/include/ou/platform.h new file mode 100644 index 0000000..ac12132 --- /dev/null +++ b/libs/ode-0.16.1/ou/include/ou/platform.h @@ -0,0 +1,398 @@ +/************************************************************************* + * * + * ODER's Utilities Library. Copyright (C) 2008-2019 Oleh Derevenko. * + * All rights reserved. e-mail: odar@eleks.com (change all "a" to "e") * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 3 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE-LESSER.TXT. Since LGPL is the extension of GPL * + * the text of GNU General Public License is also provided for * + * your information in file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * (3) The zlib/libpng license that is included with this library in * + * the file LICENSE-ZLIB.TXT * + * * + * This library is distributed WITHOUT ANY WARRANTY, including implied * + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * + * See the files LICENSE.TXT and LICENSE-LESSER.TXT or LICENSE-BSD.TXT * + * or LICENSE-ZLIB.TXT for more details. * + * * + *************************************************************************/ + +#ifndef __OU_PLATFORM_H_INCLUDED +#define __OU_PLATFORM_H_INCLUDED + + +////////////////////////////////////////////////////////////////////////// +// Target definitions + +#define _OU_TARGET_OS_GENUNIX 1 +#define _OU_TARGET_OS_WINDOWS 2 +#define _OU_TARGET_OS_QNX 3 +#define _OU_TARGET_OS_MAC 4 +#define _OU_TARGET_OS_AIX 5 +#define _OU_TARGET_OS_SUNOS 6 +#define _OU_TARGET_OS_IOS 7 + +#define _OU_TARGET_OS__MAX 8 + + +#define _OU_TARGET_BITS_32 1 +#define _OU_TARGET_BITS_64 2 + +#define _OU_TARGET_BITS__MAX 3 + + +#define _OU_TARGET_ARCH_OTHER 1 +#define _OU_TARGET_ARCH_X86 2 +#define _OU_TARGET_ARCH_IA64 3 +#define _OU_TARGET_ARCH_X64 4 +#define _OU_TARGET_ARCH_POWERPC 5 +#define _OU_TARGET_ARCH_SPARC 6 +#define _OU_TARGET_ARCH_ARM 7 +#define _OU_TARGET_ARCH_AARCH64 8 + +#define _OU_TARGET_ARCH__MAX 9 + + +////////////////////////////////////////////////////////////////////////// + +#if !defined(_OU_TARGET_OS) + + +#if defined(_WINDOWS) || defined(_WIN32) + +#define _OU_TARGET_OS _OU_TARGET_OS_WINDOWS + + +#elif defined(__QNX__) + +#define _OU_TARGET_OS _OU_TARGET_OS_QNX + + +#elif defined(__APPLE__) + +#if TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR + +#define _OU_TARGET_OS _OU_TARGET_OS_IOS + +#if !defined(MAC_OS_X_VERSION) +#define MAC_OS_X_VERSION 1050 +#endif + + +#elif TARGET_OS_MAC + +#define _OU_TARGET_OS _OU_TARGET_OS_MAC + + +#else // An unknown Apple target + +#error Build Apple target is not supported + + +#endif // // An unknown Apple target + +#elif defined(__aix__) + +#define _OU_TARGET_OS _OU_TARGET_OS_AIX + + +#elif defined(__sun__) + +#define _OU_TARGET_OS _OU_TARGET_OS_SUNOS + + +#elif defined(__unix__) + +#define _OU_TARGET_OS _OU_TARGET_OS_GENUNIX + + +#else // if no known define found + +#error Build target is not supported + + +#endif // Target OS definitions + + +#else // #if defined(_OU_TARGET_OS) + +#if _OU_TARGET_OS <= 0 || _OU_TARGET_OS >= _OU_TARGET_OS__MAX + +#error Please define a valid value for _OU_TARGET_OS + + +#endif // #if _OU_TARGET_OS <= 0 || _OU_TARGET_OS >= _OU_TARGET_OS__MAX + + +#endif // #if defined(_OU_TARGET_OS) + + +#if _OU_TARGET_OS == _OU_TARGET_OS_MAC + +#if !defined(MAC_OS_X_VERSION) + +#error Please defile preprocessor symbol MAC_OS_X_VERSION in command line (e.g. "-DMAC_OS_X_VERSION=1050" for MacOS 10.5) + + +#endif // #if !defined(MAC_OS_X_VERSION) + + +#endif // #if _OU_TARGET_OS == _OU_TARGET_OS_MAC + + +////////////////////////////////////////////////////////////////////////// + +#if !defined(_OU_TARGET_BITS) + + +#if defined(_LP64) || defined(_WIN64) + +#define _OU_TARGET_BITS _OU_TARGET_BITS_64 + + +#else // #if !defined(_LP64) + +#define _OU_TARGET_BITS _OU_TARGET_BITS_32 + + +#endif // #if !defined(_LP64) + + +#else // #if defined(_OU_TARGET_BITS) + +#if _OU_TARGET_BITS <= 0 || _OU_TARGET_BITS >= _OU_TARGET_BITS__MAX + +#error Please define a valid value for _OU_TARGET_BITS + + +#endif // #if _OU_TARGET_BITS <= 0 || _OU_TARGET_BITS >= _OU_TARGET_BITS__MAX + + +#endif // #if defined(_OU_TARGET_BITS) + + +////////////////////////////////////////////////////////////////////////// + +#if !defined(_OU_TARGET_ARCH) + + +#if defined(__i386__) || defined(_M_IX86) + +#define _OU_TARGET_ARCH _OU_TARGET_ARCH_X86 + + +#elif defined(__ia64__) || defined(_M_IA64) + +#define _OU_TARGET_ARCH _OU_TARGET_ARCH_IA64 + + +#elif defined(__x86_64__) || defined(_M_X64) || defined(_M_AMD64) + +#define _OU_TARGET_ARCH _OU_TARGET_ARCH_X64 + + +#elif defined(__ppc__) + +#define _OU_TARGET_ARCH _OU_TARGET_ARCH_POWERPC + + +#elif defined(__sparc__) + +#define _OU_TARGET_ARCH _OU_TARGET_ARCH_SPARC + + +#elif defined(__arm__) || defined(_M_ARM) || defined(TARGET_OS_IPHONE) + +#define _OU_TARGET_ARCH _OU_TARGET_ARCH_ARM + + +#elif defined(__aarch64__) + +#define _OU_TARGET_ARCH _OU_TARGET_ARCH_AARCH64 + + +#else // Unknown architecture + +#define _OU_TARGET_ARCH _OU_TARGET_ARCH_OTHER + + +#endif // Architecture definitions + + +#else // #if defined(_OU_TARGET_ARCH) + +#if _OU_TARGET_ARCH <= 0 || _OU_TARGET_ARCH >= _OU_TARGET_ARCH__MAX + +#error Please define a valid value for _OU_TARGET_ARCH + + +#endif // #if _OU_TARGET_ARCH <= 0 || _OU_TARGET_ARCH >= _OU_TARGET_ARCH__MAX + + +#endif // #if defined(_OU_TARGET_ARCH) + + +////////////////////////////////////////////////////////////////////////// +// Compiler definition + +#define _OU_COMPILER__OTHER 1 +#define _OU_COMPILER_GCC 2 +#define _OU_COMPILER_MSVC 3 + +#define _OU_COMPILER__MAX 4 + + +#define _OU_COMPILER_VERSION__OTHER 1 +#define _OU_COMPILER_VERSION_MSVC1998 2 +#define _OU_COMPILER_VERSION_GCCLT4 3 + +#define _OU_COMPILER_VERSION__MAX 4 + + +////////////////////////////////////////////////////////////////////////// + +#if !defined(_OU_COMPILER) + +#if defined(__GNUC__) + +#define _OU_COMPILER _OU_COMPILER_GCC + +#if __GNUC__ < 4 + +#define _OU_COMPILER_VERSION _OU_COMPILER_VERSION_GCCLT4 + + +#endif // compiler version + + +#elif defined(_MSC_VER) + +#define _OU_COMPILER _OU_COMPILER_MSVC + +#if _MSC_VER <= 1200 + +#define _OU_COMPILER_VERSION _OU_COMPILER_VERSION_MSVC1998 + + +#endif // compiler version + + +#else // if no known define found + +#define _OU_COMPILER _OU_COMPILER__OTHER + + +#endif // Compiler specific definitions + + +#else // #if defined(_OU_COMPILER) + +#if _OU_COMPILER <= 0 || _OU_COMPILER >= _OU_COMPILER__MAX + +#error Please define a valid value for _OU_COMPILER + + +#endif // #if _OU_COMPILER <= 0 || _OU_COMPILER >= _OU_COMPILER__MAX + + +#endif // #if defined(_OU_COMPILER) + + +#if !defined(_OU_COMPILER_VERSION) + +#define _OU_COMPILER_VERSION _OU_COMPILER_VERSION__OTHER + + +#endif // #if !defined(_OU_COMPILER_VERSION) + + +#if _OU_COMPILER_VERSION <= 0 || _OU_COMPILER_VERSION >= _OU_COMPILER_VERSION__MAX + +#error Please define a valid value for _OU_COMPILER_VERSION + + +#endif // #if _OU_COMPILER_VERSION <= 0 || _OU_COMPILER_VERSION >= _OU_COMPILER_VERSION__MAX + + +////////////////////////////////////////////////////////////////////////// +// Calling convention definition + +#if !defined(__OU_CONVENTIONS_DEFINED) + +#define __OU_CONVENTIONS_DEFINED + + +#if _OU_TARGET_OS == _OU_TARGET_OS_WINDOWS + +#define _OU_CONVENTION_METHOD +#define _OU_CONVENTION_API __stdcall +#define _OU_CONVENTION_CALLBACK __stdcall + + +#else // #if _OU_TARGET_OS != _OU_TARGET_OS_WINDOWS + +#define _OU_CONVENTION_METHOD +#define _OU_CONVENTION_API +#define _OU_CONVENTION_CALLBACK + + +#endif // #if _OU_TARGET_OS == ... + + +#endif // #if !defined(__OU_CONVENTIONS_DEFINED) + + +////////////////////////////////////////////////////////////////////////// +// _OU_ALWAYSINLINE/_OU_INLINE definition + +#if !defined(__OU_INLINES_DEFINED) + +#define __OU_INLINES_DEFINED + + +#if _OU_COMPILER == _OU_COMPILER_GCC + +#define _OU_ALWAYSINLINE__DEFINITION inline __attribute__((always_inline)) + + +#elif _OU_COMPILER == _OU_COMPILER_MSVC + +#define _OU_ALWAYSINLINE__DEFINITION inline __forceinline + + +#else // if _OU_COMPILER == _OU_COMPILER_OTHER + +#define _OU_ALWAYSINLINE__DEFINITION inline + + +#endif // #if _OU_COMPILER == ... + + +#if defined(_DEBUG) + +#define _OU_ALWAYSINLINE inline + +#define _OU_INLINE inline + + +#else // #if !defined(_DEBUG) + +#define _OU_ALWAYSINLINE _OU_ALWAYSINLINE__DEFINITION + +#define _OU_INLINE inline + + +#endif // #if !defined(_DEBUG) + + +#endif // #if !defined(__OU_INLINES_DEFINED) + + +#endif // #ifndef __OU_PLATFORM_H_INCLUDED diff --git a/libs/ode-0.16.1/ou/include/ou/simpleflags.h b/libs/ode-0.16.1/ou/include/ou/simpleflags.h new file mode 100644 index 0000000..db26617 --- /dev/null +++ b/libs/ode-0.16.1/ou/include/ou/simpleflags.h @@ -0,0 +1,334 @@ +/************************************************************************* + * * + * ODER's Utilities Library. Copyright (C) 2008-2019 Oleh Derevenko. * + * All rights reserved. e-mail: odar@eleks.com (change all "a" to "e") * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 3 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE-LESSER.TXT. Since LGPL is the extension of GPL * + * the text of GNU General Public License is also provided for * + * your information in file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * (3) The zlib/libpng license that is included with this library in * + * the file LICENSE-ZLIB.TXT * + * * + * This library is distributed WITHOUT ANY WARRANTY, including implied * + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * + * See the files LICENSE.TXT and LICENSE-LESSER.TXT or LICENSE-BSD.TXT * + * or LICENSE-ZLIB.TXT for more details. * + * * + *************************************************************************/ + +#ifndef __OU_SIMPLEFLAGS_H_INCLUDED +#define __OU_SIMPLEFLAGS_H_INCLUDED + + +#include +#include +#include +#include + +#include + + +BEGIN_NAMESPACE_OU(); + + +template +class CSimpleFlagsTemplate +{ +public: + _OU_INLINE _OU_CONVENTION_METHOD CSimpleFlagsTemplate(): + m_ctFlagsValue(0) + { + } + + _OU_INLINE _OU_CONVENTION_METHOD CSimpleFlagsTemplate(ContainerType ctFlagsValue): + m_ctFlagsValue(ctFlagsValue) + { + } + + typedef ContainerType value_type; + +public: + _OU_ALWAYSINLINE void _OU_CONVENTION_METHOD + /*void */AssignFlagsAllValues(ContainerType ctFlagsValue) + { + m_ctFlagsValue = ctFlagsValue; + } + + _OU_ALWAYSINLINE ContainerType _OU_CONVENTION_METHOD + /*ContainerType */QueryFlagsAllValues() const + { + return m_ctFlagsValue; + } + + + // Can operate both on single flag and flag set + _OU_ALWAYSINLINE void _OU_CONVENTION_METHOD + /*void */SetFlagsMaskValue(ContainerType ctFlagsMask, bool bFlagValue) + { + m_ctFlagsValue = bFlagValue + ? (m_ctFlagsValue | ctFlagsMask) + : (m_ctFlagsValue & ~ctFlagsMask); + } + + // Can operate both on single flag and flag set + _OU_ALWAYSINLINE void _OU_CONVENTION_METHOD + /*void */SignalFlagsMaskValue(ContainerType ctFlagsMask) + { + m_ctFlagsValue |= ctFlagsMask; + } + + // Can operate both on single flag and flag set + _OU_ALWAYSINLINE void _OU_CONVENTION_METHOD + /*void */DropFlagsMaskValue(ContainerType ctFlagsMask) + { + m_ctFlagsValue &= ~ctFlagsMask; + } + + + // Can operate on single flag only + // Returns previous flag value + _OU_ALWAYSINLINE bool _OU_CONVENTION_METHOD + /*bool */ToggleSingleFlagValue(ContainerType ctSingleFlag) + { + OU_ASSERT(OU_FLAGS_FLAG_IS_SINGLE(ContainerType, ctSingleFlag)); + + return ((m_ctFlagsValue ^= ctSingleFlag) & ctSingleFlag) == (ContainerType)0; + } + + // Can operate on single flag only + // Returns if modification occurred + _OU_ALWAYSINLINE bool _OU_CONVENTION_METHOD + /*bool */ModifySingleFlagValue(ContainerType ctSingleFlag, bool bFlagValue) + { + OU_ASSERT(OU_FLAGS_FLAG_IS_SINGLE(ContainerType, ctSingleFlag)); + + return ((m_ctFlagsValue & ctSingleFlag) != (ContainerType)0) != bFlagValue + ? ((m_ctFlagsValue ^= ctSingleFlag), true) + : (false); + } + + + // Modifies subset of flags + // Returns previous flags + _OU_ALWAYSINLINE ContainerType _OU_CONVENTION_METHOD + /*ContainerType */AssignFlagsByMask(ContainerType ctFlagsMask, ContainerType ctFlagsValue) + { + ContainerType ctFlagsOldValue = m_ctFlagsValue; + + m_ctFlagsValue = (ctFlagsOldValue & ~ctFlagsMask) | (ctFlagsValue & ctFlagsMask); + + return ctFlagsOldValue; + } + + // Modifies subset of flags + // Returns if modification occurred + _OU_ALWAYSINLINE bool _OU_CONVENTION_METHOD + /*bool */AlterFlagsByMask(ContainerType ctFlagsMask, ContainerType ctFlagsValue) + { + ContainerType ctFlagsOldValue = m_ctFlagsValue; + + m_ctFlagsValue = (ctFlagsOldValue & ~ctFlagsMask) | (ctFlagsValue & ctFlagsMask); + + return ((ctFlagsOldValue ^ ctFlagsValue) & ctFlagsMask) != (ContainerType)0; + } + + + // Returns value of flag or tests for any bit in a mask + _OU_ALWAYSINLINE bool _OU_CONVENTION_METHOD + /*bool */GetFlagsMaskValue(ContainerType ctFlagsMask) const + { + return (m_ctFlagsValue & ctFlagsMask) != (ContainerType)0; + } + + // Returns subset of flags + _OU_ALWAYSINLINE ContainerType _OU_CONVENTION_METHOD + /*ContainerType */QueryFlagsByMask(ContainerType ctFlagsMask) const + { + return (m_ctFlagsValue & ctFlagsMask); + } + +public: + // Signal only flag out of mask + _OU_ALWAYSINLINE bool _OU_CONVENTION_METHOD + /*bool */OnlySignalSingleFlagOutOfMask(ContainerType ctFlagsMask, ContainerType ctSingleFlag) + { + OU_ASSERT(OU_FLAGS_FLAG_IS_SINGLE(ContainerType, ctSingleFlag)); + + return !(m_ctFlagsValue & ctFlagsMask) + ? (m_ctFlagsValue |= ctSingleFlag, true) + : (false); + } + +public: + // Set value of flag indexed by enum + _OU_ALWAYSINLINE void _OU_CONVENTION_METHOD + /*void */EnumSetEnumeratedFlagValue(ContainerType ctStartingFlag, unsigned int uiEnumeratedValue, unsigned int uiEnumeratedMaximum, bool bFlagValue) + { + OU_ASSERT(uiEnumeratedValue < uiEnumeratedMaximum && OU_FLAGS_ENUMFLAGS_START_VALID(ContainerType, ctStartingFlag, uiEnumeratedMaximum)); + + SetFlagsMaskValue(ctStartingFlag << uiEnumeratedValue, bFlagValue); + } + + // Signal value of flag indexed by enum + _OU_ALWAYSINLINE void _OU_CONVENTION_METHOD + /*void */EnumSignalEnumeratedFlagValue(ContainerType ctStartingFlag, unsigned int uiEnumeratedValue, unsigned int uiEnumeratedMaximum) + { + OU_ASSERT(uiEnumeratedValue < uiEnumeratedMaximum && OU_FLAGS_ENUMFLAGS_START_VALID(ContainerType, ctStartingFlag, uiEnumeratedMaximum)); + + SignalFlagsMaskValue(ctStartingFlag << uiEnumeratedValue); + } + + // Drop value of flag indexed by enum + _OU_ALWAYSINLINE void _OU_CONVENTION_METHOD + /*void */EnumDropEnumeratedFlagValue(ContainerType ctStartingFlag, unsigned int uiEnumeratedValue, unsigned int uiEnumeratedMaximum) + { + OU_ASSERT(uiEnumeratedValue < uiEnumeratedMaximum && OU_FLAGS_ENUMFLAGS_START_VALID(ContainerType, ctStartingFlag, uiEnumeratedMaximum)); + + DropFlagsMaskValue(ctStartingFlag << uiEnumeratedValue); + } + + + // Can operate on single flag only + // Returns previous flag value + _OU_ALWAYSINLINE bool _OU_CONVENTION_METHOD + /*bool */EnumToggleEnumeratedFlagValue(ContainerType ctStartingFlag, unsigned int uiEnumeratedValue, unsigned int uiEnumeratedMaximum) + { + OU_ASSERT(uiEnumeratedValue < uiEnumeratedMaximum && OU_FLAGS_ENUMFLAGS_START_VALID(ContainerType, ctStartingFlag, uiEnumeratedMaximum)); + + return ToggleSingleFlagValue(ctStartingFlag << uiEnumeratedValue); + } + + // Can operate on single flag only + // Returns if modification occurred + _OU_ALWAYSINLINE bool _OU_CONVENTION_METHOD + /*bool */EnumModifyEnumeratedFlagValue(ContainerType ctStartingFlag, unsigned int uiEnumeratedValue, unsigned int uiEnumeratedMaximum, bool bFlagValue) + { + OU_ASSERT(uiEnumeratedValue < uiEnumeratedMaximum && OU_FLAGS_ENUMFLAGS_START_VALID(ContainerType, ctStartingFlag, uiEnumeratedMaximum)); + + return ModifySingleFlagValue(ctStartingFlag << uiEnumeratedValue, bFlagValue); + } + + + // Returns if this was the first flag signaled + _OU_ALWAYSINLINE bool _OU_CONVENTION_METHOD + /*bool */EnumSignalFirstEnumeratedFlagValue(ContainerType ctStartingFlag, unsigned int uiEnumeratedValue, unsigned int uiEnumeratedMaximum) + { + OU_ASSERT(uiEnumeratedValue < uiEnumeratedMaximum && OU_FLAGS_ENUMFLAGS_START_VALID(ContainerType, ctStartingFlag, uiEnumeratedMaximum)); + + return (AssignFlagsByMask(ctStartingFlag << uiEnumeratedValue, ctStartingFlag << uiEnumeratedValue) & OU_FLAGS_ENUMFLAGS_MASK(ContainerType, ctStartingFlag, uiEnumeratedMaximum)) == (ContainerType)0; + } + + // Returns if this was the last flag signaled + _OU_ALWAYSINLINE bool _OU_CONVENTION_METHOD + /*bool */EnumSignalLastEnumeratedFlagValue(ContainerType ctStartingFlag, unsigned int uiEnumeratedValue, unsigned int uiEnumeratedMaximum) + { + OU_ASSERT(uiEnumeratedValue < uiEnumeratedMaximum && OU_FLAGS_ENUMFLAGS_START_VALID(ContainerType, ctStartingFlag, uiEnumeratedMaximum)); + + return (AssignFlagsByMask(ctStartingFlag << uiEnumeratedValue, ctStartingFlag << uiEnumeratedValue) & OU_FLAGS_ENUMFLAGS_MASK(ContainerType, ctStartingFlag, uiEnumeratedMaximum)) == (OU_FLAGS_ENUMFLAGS_MASK(ContainerType, ctStartingFlag, uiEnumeratedMaximum) & ~(ctStartingFlag << uiEnumeratedValue)); + } + + + // Retrieve value of flag indexed by enum + _OU_ALWAYSINLINE bool _OU_CONVENTION_METHOD + /*bool */EnumGetEnumeratedFlagValue(ContainerType ctStartingFlag, unsigned int uiEnumeratedValue, unsigned int uiEnumeratedMaximum) const + { + OU_ASSERT(uiEnumeratedValue < uiEnumeratedMaximum && OU_FLAGS_ENUMFLAGS_START_VALID(ContainerType, ctStartingFlag, uiEnumeratedMaximum)); + + return GetFlagsMaskValue(ctStartingFlag << uiEnumeratedValue); + } + + // Find enum value for first flag signaled + _OU_INLINE unsigned int _OU_CONVENTION_METHOD + /*unsigned int */EnumFindFirstEnumeratedFlag(ContainerType ctStartingFlag, unsigned int uiEnumeratedMaximum) const + { + OU_ASSERT(OU_FLAGS_ENUMFLAGS_START_VALID(ContainerType, ctStartingFlag, uiEnumeratedMaximum)); + + unsigned int uiResult = 0; + + ContainerType ctFlagsMask = ctStartingFlag; + for (; uiResult < uiEnumeratedMaximum; ++uiResult, ctFlagsMask <<= 1) + { + if (GetFlagsMaskValue(ctFlagsMask)) + { + break; + } + } + + return uiResult; + } + +public: + // Signal all flags indexed by enum + _OU_ALWAYSINLINE void _OU_CONVENTION_METHOD + /*void */EnumAllSignalEnumeratedFlags(ContainerType ctStartingFlag, unsigned int uiEnumeratedMaximum) + { + OU_ASSERT(OU_FLAGS_ENUMFLAGS_START_VALID(ContainerType, ctStartingFlag, uiEnumeratedMaximum)); + + SignalFlagsMaskValue(OU_FLAGS_ENUMFLAGS_MASK(ContainerType, ctStartingFlag, uiEnumeratedMaximum)); + } + + // Drop all flags indexed by enum + _OU_ALWAYSINLINE void _OU_CONVENTION_METHOD + /*void */EnumAllDropEnumeratedFlags(ContainerType ctStartingFlag, unsigned int uiEnumeratedMaximum) + { + OU_ASSERT(OU_FLAGS_ENUMFLAGS_START_VALID(ContainerType, ctStartingFlag, uiEnumeratedMaximum)); + + DropFlagsMaskValue(OU_FLAGS_ENUMFLAGS_MASK(ContainerType, ctStartingFlag, uiEnumeratedMaximum)); + } + + + // Query all flags indexed by enum + _OU_ALWAYSINLINE ContainerType _OU_CONVENTION_METHOD + /*ContainerType */EnumAllQueryEnumeratedFlags(ContainerType ctStartingFlag, unsigned int uiEnumeratedMaximum) const + { + OU_ASSERT(OU_FLAGS_ENUMFLAGS_START_VALID(ContainerType, ctStartingFlag, uiEnumeratedMaximum)); + + return QueryFlagsByMask(OU_FLAGS_ENUMFLAGS_MASK(ContainerType, ctStartingFlag, uiEnumeratedMaximum)); + } + + // Get if any flag indexed by enum is set + _OU_ALWAYSINLINE bool _OU_CONVENTION_METHOD + /*bool */EnumAnyGetEnumeratedFlagValue(ContainerType ctStartingFlag, unsigned int uiEnumeratedMaximum) const + { + OU_ASSERT(OU_FLAGS_ENUMFLAGS_START_VALID(ContainerType, ctStartingFlag, uiEnumeratedMaximum)); + + return GetFlagsMaskValue(OU_FLAGS_ENUMFLAGS_MASK(ContainerType, ctStartingFlag, uiEnumeratedMaximum)); + } + +public: + // Store enumerated value in flags + _OU_ALWAYSINLINE void _OU_CONVENTION_METHOD + /*void */StoreFlagsEnumeratedValue(ContainerType ctEnumeratedValueMask, unsigned int uiEnumeratedValueShift, unsigned int uiEnumeratedValue) + { + OU_ASSERT(OU_FLAGS_STOREENUM_VALUE_IN_MASK(ContainerType, uiEnumeratedValue, ctEnumeratedValueMask)); + + AssignFlagsByMask(ctEnumeratedValueMask << uiEnumeratedValueShift, (ContainerType)uiEnumeratedValue << uiEnumeratedValueShift); + } + + // Retrieve enumerated value from flags + _OU_ALWAYSINLINE unsigned int _OU_CONVENTION_METHOD + /*unsigned int */RetrieveFlagsEnumeratedValue(ContainerType ctEnumeratedValueMask, unsigned int uiEnumeratedValueShift) const + { + return (unsigned int)((QueryFlagsAllValues() >> uiEnumeratedValueShift) & ctEnumeratedValueMask); + } + +private: + ContainerType m_ctFlagsValue; +}; + + +typedef CSimpleFlagsTemplate CSimpleFlags; + + +END_NAMESPACE_OU(); + + +#endif // #ifndef __OU_SIMPLEFLAGS_H_INCLUDED diff --git a/libs/ode-0.16.1/ou/include/ou/templates.h b/libs/ode-0.16.1/ou/include/ou/templates.h new file mode 100644 index 0000000..13fceb3 --- /dev/null +++ b/libs/ode-0.16.1/ou/include/ou/templates.h @@ -0,0 +1,90 @@ +/************************************************************************* + * * + * ODER's Utilities Library. Copyright (C) 2008-2019 Oleh Derevenko. * + * All rights reserved. e-mail: odar@eleks.com (change all "a" to "e") * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 3 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE-LESSER.TXT. Since LGPL is the extension of GPL * + * the text of GNU General Public License is also provided for * + * your information in file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * (3) The zlib/libpng license that is included with this library in * + * the file LICENSE-ZLIB.TXT * + * * + * This library is distributed WITHOUT ANY WARRANTY, including implied * + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * + * See the files LICENSE.TXT and LICENSE-LESSER.TXT or LICENSE-BSD.TXT * + * or LICENSE-ZLIB.TXT for more details. * + * * + *************************************************************************/ + +#ifndef __OU_TEMPLATES_H_INCLUDED +#define __OU_TEMPLATES_H_INCLUDED + + +#include +#include + + +BEGIN_NAMESPACE_OU(); + + +////////////////////////////////////////////////////////////////////////// +// Enumerated type increment/decrement operator templates + +/* + * Implementation Note: + * __attribute__((always_inline)) seems to be unimplemented for templates in GCC + */ + +template +_OU_INLINE EnumType &_OU_CONVENTION_API operator ++(EnumType &Value) +{ + Value = (EnumType)(Value + 1); + return Value; +} + +template +_OU_INLINE EnumType _OU_CONVENTION_API operator ++(EnumType &Value, int) +{ + EnumType ValueCopy = Value; + Value = (EnumType)(Value + 1); + return ValueCopy; +} + +template +_OU_INLINE EnumType &_OU_CONVENTION_API operator --(EnumType &Value) +{ + Value = (EnumType)(Value - 1); + return Value; +} + +template +_OU_INLINE EnumType _OU_CONVENTION_API operator --(EnumType &Value, int) +{ + EnumType ValueCopy = Value; + Value = (EnumType)(Value - 1); + return ValueCopy; +} + + +////////////////////////////////////////////////////////////////////////// +// Empty "signed zero" check template + +template +_OU_INLINE bool _OU_CONVENTION_API IsEmptySz(const ValueType *szLine) +{ + return !szLine || !(*szLine); +} + + +END_NAMESPACE_OU(); + + +#endif // #ifndef __OU_TEMPLATES_H_INCLUDED diff --git a/libs/ode-0.16.1/ou/include/ou/threadlocalstorage.h b/libs/ode-0.16.1/ou/include/ou/threadlocalstorage.h new file mode 100644 index 0000000..2c2fcb5 --- /dev/null +++ b/libs/ode-0.16.1/ou/include/ou/threadlocalstorage.h @@ -0,0 +1,297 @@ +/************************************************************************* + * * + * ODER's Utilities Library. Copyright (C) 2008-2019 Oleh Derevenko. * + * All rights reserved. e-mail: odar@eleks.com (change all "a" to "e") * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 3 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE-LESSER.TXT. Since LGPL is the extension of GPL * + * the text of GNU General Public License is also provided for * + * your information in file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * (3) The zlib/libpng license that is included with this library in * + * the file LICENSE-ZLIB.TXT * + * * + * This library is distributed WITHOUT ANY WARRANTY, including implied * + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * + * See the files LICENSE.TXT and LICENSE-LESSER.TXT or LICENSE-BSD.TXT * + * or LICENSE-ZLIB.TXT for more details. * + * * + *************************************************************************/ + +#ifndef _OU_THREADLOCALSTORAGE_H_INCLUDED +#define _OU_THREADLOCALSTORAGE_H_INCLUDED + + +#include + + +#if _OU_FEATURE_SET >= _OU_FEATURE_SET_TLS + +#include +#include +#include +#include +#include + +#if _OU_TARGET_OS == _OU_TARGET_OS_WINDOWS + +#include + + +#else // #if _OU_TARGET_OS != _OU_TARGET_OS_WINDOWS + +#include + + +#endif // #if _OU_TARGET_OS == ... + + +BEGIN_NAMESPACE_OU(); + + +////////////////////////////////////////////////////////////////////////// +// API specific types + +typedef CTypeSimpleWrapper HTLSKEYVALUE; +typedef CTypeSimpleWrapper HTLSKEYSELECTOR; +typedef HTLSKEYSELECTOR HTLSKEY; + +typedef void *tlsvaluetype; +typedef unsigned int tlsindextype; + +typedef void (_OU_CONVENTION_CALLBACK *CTLSValueDestructor)(tlsvaluetype vValueData); + + +#define OU_TLS_VALUE_AS_POINTER(value) (value) + + +////////////////////////////////////////////////////////////////////////// +// Internal types required for functions to be made inline + +struct CTLSStorageArray; + +struct CTLSStorageBlock +{ +/* + * Implementation Note: + * 1) Value destructors are stored in separate array since those are + * rarely accessed values and not intermixing them with data + * potentially simplifies data access (well, just theoretically, of course :)). + * 2) Destructors are stored with negative offset to allow accessing them + * without the knowledge of value count. + * 3) Well, intermixing or not intermixing has really minor impact on + * implementation characteristics, so why not to choose it after the current mood? :) + */ +private: + enum + { + TSB_RESERVEDPOINTER_HOSTARRAY, + + TSB_RESERVEDPOINTER__MAX, + }; + +public: + enum + { + TSB_LARGEST_ALIGNMENT = sizeof(void *) > sizeof(tlsvaluetype) ? sizeof(void *) : sizeof(tlsvaluetype), + }; + +public: + static inline size_t GetRequiredSize(tlsindextype iValueCount) + { + return OU_ALIGNED_SIZE(iValueCount * (sizeof(tlsvaluetype) + sizeof(CTLSValueDestructor)) + TSB_RESERVEDPOINTER__MAX * sizeof(void *), TSB_LARGEST_ALIGNMENT); + } + + static inline size_t GetZeroOffset(tlsindextype iValueCount) + { + // Since pointers and values are stored in different directions, + // alignment correction must fall entirely to either side and + // required size will not be exceeded. + return OU_ALIGNED_SIZE(iValueCount * sizeof(CTLSValueDestructor) + TSB_RESERVEDPOINTER__MAX * sizeof(void *), TSB_LARGEST_ALIGNMENT); + } + +public: + inline void SetValueData(tlsindextype iValueIndex, tlsvaluetype vValueData) + { + un.m_av_ValueDatas[iValueIndex] = vValueData; + } + + inline tlsvaluetype GetValueData(tlsindextype iValueIndex) const + { + return un.m_av_ValueDatas[iValueIndex]; + } + + inline void SetHostArray(CTLSStorageArray *psaInstance) + { + un.m_asaHostArrays[(ptrdiff_t)0 - (1 + TSB_RESERVEDPOINTER_HOSTARRAY)] = psaInstance; + } + + inline CTLSStorageArray *GetHostArray() const + { + return un.m_asaHostArrays[(ptrdiff_t)0 - (1 + TSB_RESERVEDPOINTER_HOSTARRAY)]; + } + + inline void SetValueDestructor(tlsindextype iValueIndex, CTLSValueDestructor fvValue) + { + un.m_afnValueDestructors[-((ptrdiff_t)iValueIndex) - (1 + TSB_RESERVEDPOINTER__MAX)] = fvValue; + } + + inline CTLSValueDestructor GetValueDestructor(tlsindextype iValueIndex) const + { + return un.m_afnValueDestructors[-((ptrdiff_t)iValueIndex) - (1 + TSB_RESERVEDPOINTER__MAX)]; + } + +private: + union + { + tlsvaluetype m_av_ValueDatas[1]; + CTLSValueDestructor m_afnValueDestructors[1]; + CTLSStorageArray *m_asaHostArrays[1]; + } un; +}; + + +////////////////////////////////////////////////////////////////////////// +// API declaration + +class CThreadLocalStorage +{ +public: // Safe methods + /* + * Implementation Note: + * Since the function is potentially slow and should not be frequently + * called anyway, there is no sense in creating additional overload without + * destructor parameter which would preserve current destructor procedure. + */ + static _OU_ALWAYSINLINE bool _OU_CONVENTION_API + /*bool */SetStorageValue(const HTLSKEY &hskStorageKey, tlsindextype iValueIndex, tlsvaluetype vValueData, CTLSValueDestructor fnValueDestructor=NULL) + { + bool bResult; + + CTLSStorageBlock *psbStorageBlock = GetKeyStorageBlock(hskStorageKey); + + if (psbStorageBlock) + { + psbStorageBlock->SetValueData(iValueIndex, vValueData); + psbStorageBlock->SetValueDestructor(iValueIndex, fnValueDestructor); + + bResult = true; + } + else + { + bResult = AllocateAndSetStorageValue(hskStorageKey, iValueIndex, vValueData, fnValueDestructor); + } + + return bResult; + } + + static _OU_ALWAYSINLINE tlsvaluetype _OU_CONVENTION_API + /*tlsvaluetype */GetStorageValue(const HTLSKEY &hskStorageKey, tlsindextype iValueIndex) + { + tlsvaluetype vValueData = 0; + + CTLSStorageBlock *psbStorageBlock = GetKeyStorageBlock(hskStorageKey); + + if (psbStorageBlock) + { + vValueData = psbStorageBlock->GetValueData(iValueIndex); + } + + return vValueData; + } + +public: // Unsafe methods + static _OU_ALWAYSINLINE void _OU_CONVENTION_API + /*void */UnsafeSetStorageValue(const HTLSKEY &hskStorageKey, tlsindextype iValueIndex, tlsvaluetype vValueData) + { + CTLSStorageBlock *psbStorageBlock = GetKeyStorageBlock(hskStorageKey); + psbStorageBlock->SetValueData(iValueIndex, vValueData); + } + + static _OU_ALWAYSINLINE tlsvaluetype _OU_CONVENTION_API + /*tlsvaluetype */UnsafeGetStorageValue(const HTLSKEY &hskStorageKey, tlsindextype iValueIndex) + { + CTLSStorageBlock *psbStorageBlock = GetKeyStorageBlock(hskStorageKey); + return psbStorageBlock->GetValueData(iValueIndex); + } + +private: + static bool _OU_CONVENTION_API AllocateAndSetStorageValue(const HTLSKEYSELECTOR &hksKeySelector, + tlsindextype iValueIndex, tlsvaluetype vValueData, CTLSValueDestructor fnValueDestructor); + +private: + friend class CTLSInitialization; + + static inline void _OU_CONVENTION_API SetKeyStorageBlock(const HTLSKEYSELECTOR &hskStorageKey, CTLSStorageBlock *psbInstance) + { +#if _OU_TARGET_OS == _OU_TARGET_OS_WINDOWS + + ::TlsSetValue((DWORD)(size_t)(HTLSKEYVALUE::value_type)(*(HTLSKEYSELECTOR::value_type)hskStorageKey), (LPVOID)psbInstance); + + +#else // #if _OU_TARGET_OS != _OU_TARGET_OS_WINDOWS + + pthread_setspecific((pthread_key_t)(size_t)(HTLSKEYVALUE::value_type)(*(HTLSKEYSELECTOR::value_type)hskStorageKey), (void *)psbInstance); + + +#endif // #if _OU_TARGET_OS == ... + } + + static inline CTLSStorageBlock *_OU_CONVENTION_API GetKeyStorageBlock(const HTLSKEYSELECTOR &hskStorageKey) + { +#if _OU_TARGET_OS == _OU_TARGET_OS_WINDOWS + + CTLSStorageBlock *psbStorageBlock = (CTLSStorageBlock *)::TlsGetValue((DWORD)(size_t)(HTLSKEYVALUE::value_type)(*(HTLSKEYSELECTOR::value_type)hskStorageKey)); + + +#else // #if _OU_TARGET_OS != _OU_TARGET_OS_WINDOWS + + CTLSStorageBlock *psbStorageBlock = (CTLSStorageBlock *)pthread_getspecific((pthread_key_t)(size_t)(HTLSKEYVALUE::value_type)(*(HTLSKEYSELECTOR::value_type)hskStorageKey)); + + +#endif // #if _OU_TARGET_OS == ... + + return psbStorageBlock; + } +}; + + +////////////////////////////////////////////////////////////////////////// +// Initialization/finalization + +class CTLSInitialization +{ +public: + enum EINITIALIZATIONFLAGS + { + SIF_MANUAL_CLEANUP_ON_THREAD_EXIT = 0x00000001, + }; + +public: + // Initialization must be performed from main thread + static bool _OU_CONVENTION_API InitializeTLSAPI(HTLSKEY &hskOutStorageKey, tlsindextype iValueCount, + unsigned int uiInitializationFlags=0); + static void _OU_CONVENTION_API FinalizeTLSAPI(); + + static void _OU_CONVENTION_API CleanupOnThreadExit(); + +private: + static bool _OU_CONVENTION_API InitializeTLSAPIValidated(unsigned int uiInstanceKind, + tlsindextype iValueCount, unsigned int uiInitializationFlags); + static void _OU_CONVENTION_API FinalizeTLSAPIValidated(unsigned int uiInstanceKind); +}; + + +END_NAMESPACE_OU(); + + +#endif // #if _OU_FEATURE_SET >= _OU_FEATURE_SET_TLS + + +#endif // #ifndef _OU_THREADLOCALSTORAGE_H_INCLUDED diff --git a/libs/ode-0.16.1/ou/include/ou/typewrapper.h b/libs/ode-0.16.1/ou/include/ou/typewrapper.h new file mode 100644 index 0000000..59f5cef --- /dev/null +++ b/libs/ode-0.16.1/ou/include/ou/typewrapper.h @@ -0,0 +1,111 @@ +/************************************************************************* + * * + * ODER's Utilities Library. Copyright (C) 2008-2019 Oleh Derevenko. * + * All rights reserved. e-mail: odar@eleks.com (change all "a" to "e") * + * * + * This library is free software; you can redistribute it and/or * + * modify it under the terms of EITHER: * + * (1) The GNU Lesser General Public License as published by the Free * + * Software Foundation; either version 3 of the License, or (at * + * your option) any later version. The text of the GNU Lesser * + * General Public License is included with this library in the * + * file LICENSE-LESSER.TXT. Since LGPL is the extension of GPL * + * the text of GNU General Public License is also provided for * + * your information in file LICENSE.TXT. * + * (2) The BSD-style license that is included with this library in * + * the file LICENSE-BSD.TXT. * + * (3) The zlib/libpng license that is included with this library in * + * the file LICENSE-ZLIB.TXT * + * * + * This library is distributed WITHOUT ANY WARRANTY, including implied * + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * + * See the files LICENSE.TXT and LICENSE-LESSER.TXT or LICENSE-BSD.TXT * + * or LICENSE-ZLIB.TXT for more details. * + * * + *************************************************************************/ + +#ifndef __OU_TYPEWRAPPER_H_INCLUDED +#define __OU_TYPEWRAPPER_H_INCLUDED + + +#include +#include + + +BEGIN_NAMESPACE_OU(); + + +template +struct CTypeSimpleWrapper +{ +public: + _OU_INLINE CTypeSimpleWrapper(): m_ctValue() {} + _OU_INLINE CTypeSimpleWrapper(const ContainedType &ctValue): m_ctValue(ctValue) {} + // _OU_INLINE CTypeSimpleWrapper(const CTypeSimpleWrapper &twOtherWrapper): m_ctValue(twOtherWrapper.m_ctValue) {} -- do not uncomment!!! in MSVC 6.0 optimization fails with it. :-/ + + typedef ContainedType value_type; + + _OU_INLINE bool operator ==(const CTypeSimpleWrapper &twOtherWrapper) const { return m_ctValue == twOtherWrapper.m_ctValue; } + _OU_INLINE bool operator !=(const CTypeSimpleWrapper &twOtherWrapper) const { return !(operator ==(twOtherWrapper)); } + + _OU_INLINE bool operator <(const CTypeSimpleWrapper &twOtherWrapper) const { return m_ctValue < twOtherWrapper.m_ctValue; } + _OU_INLINE bool operator >(const CTypeSimpleWrapper &twOtherWrapper) const { return twOtherWrapper.operator <(*this); } + _OU_INLINE bool operator <=(const CTypeSimpleWrapper &twOtherWrapper) const { return !(twOtherWrapper.operator <(*this)); } + _OU_INLINE bool operator >=(const CTypeSimpleWrapper &twOtherWrapper) const { return !(operator <(twOtherWrapper)); } + + // _OU_INLINE operator bool() const { return !!m_ctValue; } -- casting to bool is too dangerous - it tends to be used instead of casting to int + _OU_INLINE bool operator !() const { return !m_ctValue; } + + _OU_INLINE CTypeSimpleWrapper &operator =(const ContainedType &ctValue) { m_ctValue = ctValue; return *this; } + _OU_INLINE CTypeSimpleWrapper &operator =(const CTypeSimpleWrapper &twOtherWrapper) { m_ctValue = twOtherWrapper.m_ctValue; return *this; } + + _OU_INLINE operator const ContainedType &() const { return m_ctValue; } + _OU_INLINE operator ContainedType &() { return m_ctValue; } + +private: + ContainedType m_ctValue; +}; + + +template +_OU_INLINE bool _OU_CONVENTION_API operator ==(const CTypeSimpleWrapper &twLeftWrapper, const ContainedType &ctRightValue) { return (const ContainedType &)twLeftWrapper == ctRightValue; } + +template +_OU_INLINE bool _OU_CONVENTION_API operator ==(const ContainedType &ctLeftValue, const CTypeSimpleWrapper &twRightWrapper) { return ctLeftValue == (const ContainedType &)twRightWrapper; } + +template +_OU_INLINE bool _OU_CONVENTION_API operator !=(const CTypeSimpleWrapper &twLeftWrapper, const ContainedType &ctRightValue) { return !(twLeftWrapper == ctRightValue); } + +template +_OU_INLINE bool _OU_CONVENTION_API operator !=(const ContainedType &ctLeftValue, const CTypeSimpleWrapper &twRightWrapper) { return !(ctLeftValue == twRightWrapper); } + + +template +_OU_INLINE bool _OU_CONVENTION_API operator <(const CTypeSimpleWrapper &twLeftWrapper, const ContainedType &ctRightValue) { return (const ContainedType &)twLeftWrapper < ctRightValue; } + +template +_OU_INLINE bool _OU_CONVENTION_API operator <(const ContainedType &ctLeftValue, const CTypeSimpleWrapper &twRightWrapper) { return ctLeftValue < (const ContainedType &)twRightWrapper; } + +template +_OU_INLINE bool _OU_CONVENTION_API operator >(const CTypeSimpleWrapper &twLeftWrapper, const ContainedType &ctRightValue) { return ctRightValue < twLeftWrapper; } + +template +_OU_INLINE bool _OU_CONVENTION_API operator >(const ContainedType &ctLeftValue, const CTypeSimpleWrapper &twRightWrapper) { return twRightWrapper < ctLeftValue; } + +template +_OU_INLINE bool _OU_CONVENTION_API operator <=(const CTypeSimpleWrapper &twLeftWrapper, const ContainedType &ctRightValue) { return !(ctRightValue < twLeftWrapper); } + +template +_OU_INLINE bool _OU_CONVENTION_API operator <=(const ContainedType &ctLeftValue, const CTypeSimpleWrapper &twRightWrapper) { return !(twRightWrapper < ctLeftValue); } + +template +_OU_INLINE bool _OU_CONVENTION_API operator >=(const CTypeSimpleWrapper &twLeftWrapper, const ContainedType &ctRightValue) { return !(twLeftWrapper < ctRightValue); } + +template +_OU_INLINE bool _OU_CONVENTION_API operator >=(const ContainedType &ctLeftValue, const CTypeSimpleWrapper &twRightWrapper) { return !(ctLeftValue < twRightWrapper); } + + +END_NAMESPACE_OU(); + + +#endif // #ifndef __OU_TYPEWRAPPER_H_INCLUDED -- cgit v1.2.1