first commit

This commit is contained in:
2024-06-10 12:48:14 +03:00
commit d54c9805b3
1398 changed files with 739400 additions and 0 deletions

View File

@@ -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

View File

@@ -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:

View File

@@ -0,0 +1,188 @@
/*************************************************************************
* *
* ODER's Utilities Library. Copyright (C) 2008-2024 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 <ou/customization.h>
#include <ou/namespace.h>
/**
* \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 <assert.h>
#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

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,367 @@
/*************************************************************************
* *
* ODER's Utilities Library. Copyright (C) 2008-2024 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 <ou/flagsdefines.h>
#include <ou/atomic.h>
#include <ou/assert.h>
#include <ou/namespace.h>
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

View File

@@ -0,0 +1,149 @@
/*************************************************************************
* *
* ODER's Utilities Library. Copyright (C) 2008-2024 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 <ou/namespace.h>
#include <ou/inttypes.h>
#include <ou/platform.h>
#include <stddef.h>
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

View File

@@ -0,0 +1,256 @@
/*************************************************************************
* *
* ODER's Utilities Library. Copyright (C) 2008-2024 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 <ou/assert.h>
#include <ou/macros.h>
#include <ou/platform.h>
#include <ou/namespace.h>
BEGIN_NAMESPACE_OU();
//////////////////////////////////////////////////////////////////////////
// Helper template definitions
template<typename ElementType>
struct CTypeStandardEqual
{
_OU_INLINE bool _OU_CONVENTION_METHOD operator ()(const ElementType &etLeftElement, const ElementType &etRightElement) const
{
return etLeftElement == etRightElement;
}
};
template<typename ElementType>
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 never need a nontrivial constructor
* and it is acceptable to have it as template parameter.
*/
template<typename EnumType, const EnumType EnumMax, typename ElementType, const int Instance=0, class CElementEqualType=CTypeStandardEqual<ElementType> >
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 never need
* a nontrivial constructor and it is acceptable to have them
* as template parameters.
*/
template<typename EnumType, const EnumType EnumMax, typename ElementType, const int Instance=0, class CElementLessType=CTypeStandardLess<ElementType> >
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

View File

@@ -0,0 +1,51 @@
/*************************************************************************
* *
* ODER's Utilities Library. Copyright (C) 2008-2024 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

View File

@@ -0,0 +1,35 @@
/*************************************************************************
* *
* ODER's Utilities Library. Copyright (C) 2008-2024 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 <ou/simpleflags.h>
#include <ou/atomicflags.h>
#endif // #ifndef __OU_FLAGS_H_INCLUDED

View File

@@ -0,0 +1,37 @@
/*************************************************************************
* *
* ODER's Utilities Library. Copyright (C) 2008-2024 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

View File

@@ -0,0 +1,136 @@
/*************************************************************************
* *
* ODER's Utilities Library. Copyright (C) 2008-2024 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 <ou/namespace.h>
#include <ou/platform.h>
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 <inttypes.h>
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

View File

@@ -0,0 +1,79 @@
/*************************************************************************
* *
* ODER's Utilities Library. Copyright (C) 2008-2024 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 <stddef.h>
//////////////////////////////////////////////////////////////////////////
// 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 <ou/inttypes.h> for it to work.
* I do not include the header automaticaly to keep <macros.h>
* 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

View File

@@ -0,0 +1,48 @@
/*************************************************************************
* *
* ODER's Utilities Library. Copyright (C) 2008-2024 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 <ou/namespace.h>
#include <ou/platform.h>
#include <stddef.h>
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

View File

@@ -0,0 +1,43 @@
/*************************************************************************
* *
* ODER's Utilities Library. Copyright (C) 2008-2024 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

View File

@@ -0,0 +1,398 @@
/*************************************************************************
* *
* ODER's Utilities Library. Copyright (C) 2008-2024 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 define 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

View File

@@ -0,0 +1,334 @@
/*************************************************************************
* *
* ODER's Utilities Library. Copyright (C) 2008-2024 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 <ou/flagsdefines.h>
#include <ou/assert.h>
#include <ou/inttypes.h>
#include <ou/namespace.h>
#include <stddef.h>
BEGIN_NAMESPACE_OU();
template<typename ContainerType>
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<uint32ou> CSimpleFlags;
END_NAMESPACE_OU();
#endif // #ifndef __OU_SIMPLEFLAGS_H_INCLUDED

View File

@@ -0,0 +1,90 @@
/*************************************************************************
* *
* ODER's Utilities Library. Copyright (C) 2008-2024 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 <ou/macros.h>
#include <ou/namespace.h>
BEGIN_NAMESPACE_OU();
//////////////////////////////////////////////////////////////////////////
// Enumerated type increment/decrement operator templates
/*
* Implementation Note:
* __attribute__((always_inline)) seems to be unimplemented for templates in GCC
*/
template<typename EnumType>
_OU_INLINE EnumType &_OU_CONVENTION_API operator ++(EnumType &Value)
{
Value = (EnumType)(Value + 1);
return Value;
}
template<typename EnumType>
_OU_INLINE EnumType _OU_CONVENTION_API operator ++(EnumType &Value, int)
{
EnumType ValueCopy = Value;
Value = (EnumType)(Value + 1);
return ValueCopy;
}
template<typename EnumType>
_OU_INLINE EnumType &_OU_CONVENTION_API operator --(EnumType &Value)
{
Value = (EnumType)(Value - 1);
return Value;
}
template<typename EnumType>
_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<typename ValueType>
_OU_INLINE bool _OU_CONVENTION_API IsEmptySz(const ValueType *szLine)
{
return !szLine || !(*szLine);
}
END_NAMESPACE_OU();
#endif // #ifndef __OU_TEMPLATES_H_INCLUDED

View File

@@ -0,0 +1,297 @@
/*************************************************************************
* *
* ODER's Utilities Library. Copyright (C) 2008-2024 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 <ou/features.h>
#if _OU_FEATURE_SET >= _OU_FEATURE_SET_TLS
#include <ou/typewrapper.h>
#include <ou/macros.h>
#include <ou/assert.h>
#include <ou/platform.h>
#include <ou/namespace.h>
#if _OU_TARGET_OS == _OU_TARGET_OS_WINDOWS
#include <windows.h>
#else // #if _OU_TARGET_OS != _OU_TARGET_OS_WINDOWS
#include <pthread.h>
#endif // #if _OU_TARGET_OS == ...
BEGIN_NAMESPACE_OU();
//////////////////////////////////////////////////////////////////////////
// API specific types
typedef CTypeSimpleWrapper<void *, 1> HTLSKEYVALUE;
typedef CTypeSimpleWrapper<HTLSKEYVALUE *, 0> 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

View File

@@ -0,0 +1,111 @@
/*************************************************************************
* *
* ODER's Utilities Library. Copyright (C) 2008-2024 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 <ou/platform.h>
#include <ou/namespace.h>
BEGIN_NAMESPACE_OU();
template<typename ContainedType, const int Instance=0>
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<typename ContainedType, const int Instance>
_OU_INLINE bool _OU_CONVENTION_API operator ==(const CTypeSimpleWrapper<ContainedType, Instance> &twLeftWrapper, const ContainedType &ctRightValue) { return (const ContainedType &)twLeftWrapper == ctRightValue; }
template<typename ContainedType, const int Instance>
_OU_INLINE bool _OU_CONVENTION_API operator ==(const ContainedType &ctLeftValue, const CTypeSimpleWrapper<ContainedType, Instance> &twRightWrapper) { return ctLeftValue == (const ContainedType &)twRightWrapper; }
template<typename ContainedType, const int Instance>
_OU_INLINE bool _OU_CONVENTION_API operator !=(const CTypeSimpleWrapper<ContainedType, Instance> &twLeftWrapper, const ContainedType &ctRightValue) { return !(twLeftWrapper == ctRightValue); }
template<typename ContainedType, const int Instance>
_OU_INLINE bool _OU_CONVENTION_API operator !=(const ContainedType &ctLeftValue, const CTypeSimpleWrapper<ContainedType, Instance> &twRightWrapper) { return !(ctLeftValue == twRightWrapper); }
template<typename ContainedType, const int Instance>
_OU_INLINE bool _OU_CONVENTION_API operator <(const CTypeSimpleWrapper<ContainedType, Instance> &twLeftWrapper, const ContainedType &ctRightValue) { return (const ContainedType &)twLeftWrapper < ctRightValue; }
template<typename ContainedType, const int Instance>
_OU_INLINE bool _OU_CONVENTION_API operator <(const ContainedType &ctLeftValue, const CTypeSimpleWrapper<ContainedType, Instance> &twRightWrapper) { return ctLeftValue < (const ContainedType &)twRightWrapper; }
template<typename ContainedType, const int Instance>
_OU_INLINE bool _OU_CONVENTION_API operator >(const CTypeSimpleWrapper<ContainedType, Instance> &twLeftWrapper, const ContainedType &ctRightValue) { return ctRightValue < twLeftWrapper; }
template<typename ContainedType, const int Instance>
_OU_INLINE bool _OU_CONVENTION_API operator >(const ContainedType &ctLeftValue, const CTypeSimpleWrapper<ContainedType, Instance> &twRightWrapper) { return twRightWrapper < ctLeftValue; }
template<typename ContainedType, const int Instance>
_OU_INLINE bool _OU_CONVENTION_API operator <=(const CTypeSimpleWrapper<ContainedType, Instance> &twLeftWrapper, const ContainedType &ctRightValue) { return !(ctRightValue < twLeftWrapper); }
template<typename ContainedType, const int Instance>
_OU_INLINE bool _OU_CONVENTION_API operator <=(const ContainedType &ctLeftValue, const CTypeSimpleWrapper<ContainedType, Instance> &twRightWrapper) { return !(twRightWrapper < ctLeftValue); }
template<typename ContainedType, const int Instance>
_OU_INLINE bool _OU_CONVENTION_API operator >=(const CTypeSimpleWrapper<ContainedType, Instance> &twLeftWrapper, const ContainedType &ctRightValue) { return !(twLeftWrapper < ctRightValue); }
template<typename ContainedType, const int Instance>
_OU_INLINE bool _OU_CONVENTION_API operator >=(const ContainedType &ctLeftValue, const CTypeSimpleWrapper<ContainedType, Instance> &twRightWrapper) { return !(ctLeftValue < twRightWrapper); }
END_NAMESPACE_OU();
#endif // #ifndef __OU_TYPEWRAPPER_H_INCLUDED