"Fossies" - the Fresh Open Source Software Archive

Member "muscle/support/MuscleSupport.h" (21 Nov 2020, 93203 Bytes) of package /linux/privat/muscle7.62.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "MuscleSupport.h" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 7.61_vs_7.62.

    1 /* This file is Copyright 2000-2013 Meyer Sound Laboratories Inc.  See the included LICENSE.txt file for details. */
    2 
    3 /******************************************************************************
    4 /
    5 /     File:     MuscleSupport.h
    6 /
    7 /     Description:  Standard types, macros, functions, etc, for MUSCLE.
    8 /
    9 *******************************************************************************/
   10 
   11 #ifndef MuscleSupport_h
   12 #define MuscleSupport_h
   13 
   14 #define MUSCLE_VERSION_STRING "7.62" /**< The current version of the MUSCLE distribution, expressed as an ASCII string */
   15 #define MUSCLE_VERSION        76200  /**< Current version, expressed as decimal Mmmbb, where (M) is the number before the decimal point, (mm) is the number after the decimal point, and (bb) is reserved */
   16 
   17 /*! \mainpage MUSCLE Documentation Page
   18  *
   19  * The MUSCLE API provides a robust, efficient, scalable, cross-platform, client-server messaging system 
   20  * for network-distributed applications for Linux, MacOS/X, BSD, Windows, BeOS, and other operating 
   21  * systems.  It can be compiled using any C++ compiler that supports C++03 or higher (although C++11 or
   22  * higher is preferred) and can run under any OS with a TCP/IP stack and BSD-style sockets API.
   23  *
   24  * MUSCLE allows an arbitrary number of client programs (each of which may be running on a separate computer and/or 
   25  * under a different OS) to communicate with each other in a many-to-many structured-message-passing style.  It 
   26  * employs a central server to which client programs may connect or disconnect at any time.  In addition to the client-server system, MUSCLE contains classes 
   27  * to support peer-to-peer message-queue connections, as well as some handy miscellaneous utility 
   28  * classes, all of which are documented here.
   29  *
   30  * All classes documented here should compile under most modern OS's with a modern C++ compiler.
   31  * Where platform-specific code is necessary, it has been provided (inside \#ifdef's) for various OS's.
   32  * C++ templates are used where appropriate; C++ exceptions are avoided in favor of returned error-codes.  The code is usable 
   33  * in multithreaded environments, as long as you are careful.
   34  *
   35  * An examples-oriented tour of the various MUSCLE APIs can be found <a href="https://public.msli.com/lcs/muscle/muscle/html/muscle-by-example/site/index.html">here</a>.
   36  *
   37  * As distributed, the server side of the software is ready to compile and run, but to do much with it 
   38  * you'll want to write your own client software.  Example client software can be found in the "test" 
   39  * subdirectory.
   40  */
   41 
   42 #include <assert.h>  /* for assert() */
   43 #include <string.h>  /* for memcpy() */
   44 #include <stdio.h>
   45 #include <stdlib.h>
   46 #include <errno.h>   /* for errno */
   47 
   48 /* Define this if the default FD_SETSIZE is too small for you (i.e. under Windows it's only 64) */
   49 #if defined(MUSCLE_FD_SETSIZE)
   50 # if defined(FD_SETSIZE)
   51 #  error "MuscleSupport.h:  Can not redefine FD_SETSIZE, someone else has already defined it!  You need to include MuscleSupport.h before including any other header files that define FD_SETSIZE."
   52 # else
   53 #  define FD_SETSIZE MUSCLE_FD_SETSIZE
   54 # endif
   55 #endif
   56 
   57 /* If we are in an environment where known assembly is available, make a note of that fact */
   58 #ifndef MUSCLE_AVOID_INLINE_ASSEMBLY
   59 # if defined(__GNUC__)
   60 #  if defined(__i386__) || defined(__i486__) || defined(__i586__) || defined(__i686__) || defined(__amd64__) || defined(__x86_64__) || defined(__x86__) || defined(__pentium__) || defined(__pentiumpro__) || defined(__k6__) || defined(_M_AMD64)
   61 #   define MUSCLE_USE_X86_INLINE_ASSEMBLY 1
   62 #  elif defined(__PPC__) || defined(__POWERPC__)
   63 #   define MUSCLE_USE_POWERPC_INLINE_ASSEMBLY 1
   64 #  endif
   65 # elif defined(_MSC_VER) && (defined(_X86_) || defined(_M_IX86))
   66 #  define MUSCLE_USE_X86_INLINE_ASSEMBLY 1
   67 # endif
   68 #endif
   69 
   70 #if (_MSC_VER >= 1310)
   71 # define MUSCLE_USE_MSVC_SWAP_FUNCTIONS 1
   72 #endif
   73 
   74 #if (_MSC_VER >= 1300) && !defined(MUSCLE_AVOID_WINDOWS_STACKTRACE)
   75 # define MUSCLE_USE_MSVC_STACKWALKER 1
   76 #endif
   77 
   78 #ifdef __cplusplus
   79 # if !defined(MUSCLE_AVOID_CPLUSPLUS11) && (__cplusplus < 201100) && !defined(_MSVC_LANG)
   80 #  define MUSCLE_AVOID_CPLUSPLUS11
   81 # endif
   82 # ifndef MUSCLE_AVOID_CPLUSPLUS11
   83 #  if !defined(MUSCLE_USE_PTHREADS) && !defined(MUSCLE_SINGLE_THREAD_ONLY) && !defined(MUSCLE_AVOID_CPLUSPLUS11_THREADS)
   84 #   define MUSCLE_USE_CPLUSPLUS11_THREADS
   85 #  endif
   86 #  if defined(_MSC_VER) && (_MSC_VER < 1900)  // MSVC2013 and older don't implement constexpr, sigh
   87 #   define MUSCLE_CONSTEXPR            /**< This tag indicates that the function or variable it decorates can be evaluated at compile time.  (Expands to keyword constexpr iff MUSCLE_AVOID_CPLUSPLUS11 is not defined) */
   88 #  else
   89 #   define MUSCLE_CONSTEXPR constexpr  /**< This tag indicates that the function or variable it decorates can be evaluated at compile time.  (Expands to keyword constexpr iff MUSCLE_AVOID_CPLUSPLUS11 is not defined) */
   90 #   define MUSCLE_CONSTEXPR_IS_SUPPORTED /**< defined iff we are being compiled on a compiler (and in a compiler-mode) that supports the constexpr keyword */
   91 #  endif
   92 #  include <type_traits>  // for static_assert()
   93 #  include <utility>      // for std::move()
   94 #  if !defined(__clang__) && defined(__GNUC__) && (__GNUC__ == 4) && (__GNUC_MINOR__ < 7)
   95 #   define MUSCLE_FINAL_CLASS          /**< If defined, this tag indicates that the class should not be subclassed.  (Expands to keyword "final" iff MUSCLE_AVOID_CPLUSPLUS11 is not defined) */ /* work-around for g++ bug #50811 */
   96 #  else
   97 #   define MUSCLE_FINAL_CLASS final   /**< This tag indicates that the class it decorates should not be subclassed.  (Expands to keyword "final" iff MUSCLE_AVOID_CPLUSPLUS11 is not defined) */
   98 #  endif
   99 # else
  100 #  define MUSCLE_FINAL_CLASS          /**< This tag indicates that the class it decorates should not be subclassed.  (Expands to keyword "final" iff MUSCLE_AVOID_CPLUSPLUS11 is not defined) */
  101 #  define MUSCLE_CONSTEXPR            /**< This tag indicates that the function or variable it decorates can be evaluated at compile time.  (Expands to keyword constexpr iff MUSCLE_AVOID_CPLUSPLUS11 is not defined) */
  102 # endif
  103 #else
  104 # define NEW_H_NOT_AVAILABLE          /**< Defined iff C++ "new" include file isn't available (e.g. because we're on an ancient platform) */
  105 #endif
  106 
  107 #if !defined(MUSCLE_AVOID_STDINT) && (defined(MUSCLE_AVOID_CPLUSPLUS11) || (defined(_MSC_VER) && (_MSC_VER < 1800)))
  108 # define MUSCLE_AVOID_STDINT  // No sense trying to use cstdint on older compilers that we know do not provide it
  109 #endif
  110 
  111 #ifndef MUSCLE_AVOID_STDINT
  112 # include <stdint.h>
  113 # include <stddef.h>  // for ptrdiff_t when compiling as C code
  114 # ifdef __cplusplus
  115 #  include <cinttypes>
  116 # else
  117 #  include <inttypes.h>
  118 # endif
  119 #endif
  120 
  121 // For non-C++-11 environments, we don't have the ability to make a class final, so we just define 
  122 // MUSCLE_FINAL_CLASS to expand to nothing, and leave it up to the user to know not to subclass the class.
  123 #ifndef MUSCLE_FINAL_CLASS
  124 # define MUSCLE_FINAL_CLASS
  125 #endif
  126 
  127 #ifndef MUSCLE_CONSTEXPR
  128 # define MUSCLE_CONSTEXPR  /**< This tag indicates that the function or variable it decorates can be evaluated at compile time.  (Expands to keyword constexpr iff MUSCLE_AVOID_CPLUSPLUS11 is not defined) */
  129 #endif
  130 
  131 /* Borland C++ builder also runs under Win32, but it doesn't set this flag So we'd better set it ourselves. */
  132 #if defined(__BORLANDC__) || defined(__WIN32__) || defined(_MSC_VER) || defined(_WIN32)
  133 # ifndef WIN32
  134 #  define WIN32 1
  135 # endif
  136 #endif
  137 
  138 /* Win32 can't handle this stuff, it's too lame */
  139 #ifdef WIN32
  140 # define SELECT_ON_FILE_DESCRIPTORS_NOT_AVAILABLE  /** Defined iff we're not allowed to select() on file descriptor (e.g. because we're on Windows) */
  141 # define UNISTD_H_NOT_AVAILABLE        /**< Defined iff <unistd.h> header isn't available (e.g. because we're on an ancient platform, or Windows) */
  142 # ifndef _MSC_VER  /* 7/3/2006: Mika's patch allows VC++ to use newnothrow */
  143 #  define NEW_H_NOT_AVAILABLE          /**< Defined iff C++ <new> header isn't available (e.g. because we're on an ancient platform) */
  144 # endif
  145 #elif defined(__BEOS__) && !defined(__HAIKU__)
  146 # define SELECT_ON_FILE_DESCRIPTORS_NOT_AVAILABLE
  147 #endif
  148 
  149 #ifndef UNISTD_H_NOT_AVAILABLE
  150 # include <unistd.h>
  151 #endif
  152 
  153 #ifndef NEW_H_NOT_AVAILABLE
  154 # include <new>
  155 # ifndef __MWERKS__
  156 using std::bad_alloc;
  157 using std::nothrow_t;
  158 using std::nothrow;
  159 #  if (defined(_MSC_VER))
  160 // VC++ 6.0 and earlier lack this definition
  161 #   if (_MSC_VER < 1300)
  162 inline void __cdecl operator delete(void *p, const std::nothrow_t&) _THROW0() {delete(p);}
  163 #   endif
  164 #  else
  165 using std::new_handler;
  166 using std::set_new_handler;
  167 #  endif
  168 # endif
  169 #else
  170 # define MUSCLE_AVOID_NEWNOTHROW /**< If defined, the newnothrow macro will expand to "new" rather than to "new (nothrow)" */
  171 #endif
  172 
  173 #ifndef newnothrow
  174 # ifdef MUSCLE_AVOID_NEWNOTHROW
  175 #  define newnothrow new            /**< newnothrow is a shortcut for "new (nothrow)", unless MUSCLE_AVOID_NEWNOTHROW is defined, in which case it becomes a synonym for plain old "new" */
  176 # else
  177 #  define newnothrow new (nothrow)  /**< newnothrow is a shortcut for "new (nothrow)", unless MUSCLE_AVOID_NEWNOTHROW is defined, in which case it becomes a synonym for plain old "new" */
  178 # endif
  179 #endif
  180 
  181 #ifndef DOXYGEN_SHOULD_IGNORE_THIS
  182 // These macros are implementation details, please ignore them
  183 # define ___MUSCLE_UNIQUE_NAME_AUX1(name, line) name##line
  184 # define ___MUSCLE_UNIQUE_NAME_AUX2(name, line) ___MUSCLE_UNIQUE_NAME_AUX1(name, line)
  185 #endif
  186 
  187 /** This macro expands to a variable name which is (per-file) unique and unreferenceable.
  188   * This can be useful to help make sure the temporary variables in your macros don't
  189   * collide with each other.
  190   */
  191 #define MUSCLE_UNIQUE_NAME ___MUSCLE_UNIQUE_NAME_AUX2(__uniqueName, __LINE__)
  192 
  193 /** This macro declares an object on the stack with the specified argument(s). */
  194 #define DECLARE_ANONYMOUS_STACK_OBJECT(objType, ...) objType MUSCLE_UNIQUE_NAME = objType(__VA_ARGS__)
  195 
  196 #ifdef MUSCLE_AVOID_ASSERTIONS
  197 # define MASSERT(x,msg) /**< assertion macro.  Unless -DMUSCLE_AVOID_ASSERTIONS is specified, this macro will crash the program (with the error message in its second argument) if its first argument evaluates to false. */
  198 #else
  199 # define MASSERT(x,msg) {if(!(x)) MCRASH(msg)} /**< assertion macro.  Unless -DMUSCLE_AVOID_ASSERTIONS is specified, this macro will crash the program (with the error message in its second argument) if its first argument evaluates to false. */
  200 #endif
  201 
  202 /** This macro crashes the process with the specified error message. */
  203 #define MCRASH(msg) {muscle::LogTime(muscle::MUSCLE_LOG_CRITICALERROR, "ASSERTION FAILED: (%s:%i) %s\n", __FILE__,__LINE__,msg); muscle::LogStackTrace(muscle::MUSCLE_LOG_CRITICALERROR); muscle::Crash();}
  204 
  205 /** This macro immediately and rudely exits the process (by calling ExitWithoutCleanup(retVal)) after logging the specified critical error message. */
  206 #define MEXIT(retVal,msg) {muscle::LogTime(muscle::MUSCLE_LOG_CRITICALERROR, "ASSERTION FAILED: (%s:%i) %s\n", __FILE__,__LINE__,msg); muscle::LogStackTrace(MUSCLE_LOG_CRITICALERROR); ExitWithoutCleanup(retVal);}
  207 
  208 /** This macro logs an out-of-memory warning that includes the current filename and source-code line number.  WARN_OUT_OF_MEMORY() should be called whenever newnothrow or malloc() return NULL. */
  209 #define WARN_OUT_OF_MEMORY muscle::WarnOutOfMemory(__FILE__, __LINE__)
  210 
  211 /** This macro logs an out-of-memory warning that includes the current filename and source-code line number, and then returns B_OUT_OF_MEMORY.  RETURN_OUT_OF_MEMORY() may be called whenever newnothrow or malloc() return NULL inside a function that returns a status_t. */
  212 #define RETURN_OUT_OF_MEMORY {muscle::WarnOutOfMemory(__FILE__, __LINE__); return B_OUT_OF_MEMORY;}
  213 
  214 /** This macro logs a warning message including the the current filename and source-code line number.  It can be useful for debugging/execution-path-tracing in environments without a debugger. */
  215 #define MCHECKPOINT muscle::LogTime(muscle::MUSCLE_LOG_WARNING, "Reached checkpoint at %s:%i\n", __FILE__, __LINE__)
  216 
  217 #if !defined(MUSCLE_64_BIT_PLATFORM)
  218 # if defined(PTRDIFF_MAX)
  219 #  if (PTRDIFF_MAX > 4294967296)
  220 #   define MUSCLE_64_BIT_PLATFORM 1
  221 #  endif
  222 # elif defined(__osf__) || defined(__amd64__) || defined(__PPC64__) || defined(__x86_64__) || defined(_M_AMD64)
  223 #  define MUSCLE_64_BIT_PLATFORM 1  // auto-define it if it wasn't defined in the Makefile
  224 # endif
  225 #endif
  226 
  227 #ifdef __cplusplus
  228 template<typename T, int size> MUSCLE_CONSTEXPR unsigned int ARRAYITEMS(T(&)[size]) {return size;}  /**< Returns # of items in the array.  Will error out at compile time if you try to call it with a pointer as an argument.  */
  229 #else
  230 # define ARRAYITEMS(x) (sizeof(x)/sizeof(x[0]))  /**< Returns # of items in the array.  This primitive C-compatible implementation will return an incorrect value if called with a pointer as an argument. */
  231 #endif
  232 typedef void * muscleVoidPointer;  /**< Synonym for a (void *) -- it's a bit easier, syntax-wise, to use this type than (void *) directly in some cases. */
  233 
  234 #if defined(__BEOS__) || defined(__HAIKU__)
  235 # include <support/Errors.h>
  236 # include <support/ByteOrder.h>  /* might as well use the real thing (and avoid complaints about duplication) */
  237 # include <support/SupportDefs.h>
  238 # include <support/TypeConstants.h>
  239 # if !((defined(BONE))||(defined(BONE_VERSION))||(defined(__HAIKU__)))
  240 #  define BEOS_OLD_NETSERVER
  241 # endif
  242 #else
  243    enum {
  244       CB_ERROR    = -1,        /**< For C programs: A value typically returned by a function or method with return type status_t, to indicate that it failed.  (When checking the value, it's better to check against B_NO_ERROR though, in case other failure values are defined in the future) */
  245       CB_NO_ERROR = 0,         /**< For C programs: The value returned by a function or method with return type status_t, to indicate that it succeeded with no errors. */
  246       CB_OK       = CB_NO_ERROR /**< For C programs: Synonym for CB_NO_ERROR */
  247    };
  248 # ifdef __ATHEOS__
  249 #  include </ainc/atheos/types.h>
  250 # else
  251 #  ifndef MUSCLE_TYPES_PREDEFINED  /* certain (ahem) projects already set these themselves... */
  252 #   ifndef __cplusplus
  253 #    define true                     1        /**< In C++, true is defined as non-zero, here as 1 */
  254 #    define false                    0        /**< In C++, false is defined as zero */
  255 #   endif
  256     typedef unsigned char           uchar;    /**< uchar is a synonym for "unsigned char" */
  257     typedef unsigned short          unichar;  /**< unichar is a synonym for "unsigned short" */
  258 #   ifdef MUSCLE_AVOID_STDINT
  259      typedef signed char             int8;     /**< int8 is an 8-bit signed integer type */
  260      typedef unsigned char           uint8;    /**< uint8 is an 8-bit unsigned integer type */
  261      typedef short                   int16;    /**< int16 is a 16-bit signed integer type */
  262      typedef unsigned short          uint16;   /**< uint16 is a 16-bit unsigned integer type */
  263 #    if defined(MUSCLE_64_BIT_PLATFORM)        /* some 64bit systems will have long=64-bit, int=32-bit */
  264       typedef int                    int32;    /**< int32 is a 32-bit signed integer type */
  265 #     ifndef _UINT32
  266        typedef unsigned int          uint32;   /**< uint32 is a 32-bit unsigned integer type */
  267 #      define _UINT32                          /**< Avoid conflict with typedef in OS/X Leopard system header */
  268 #     endif
  269 #    else
  270       typedef int                    int32;    /**< int32 is a 32-bit signed integer type */
  271 #     ifndef _UINT32
  272        typedef unsigned int          uint32;   /**< uint32 is a 32-bit unsigned integer type */
  273 #      define _UINT32                          /**< Avoid conflict with typedef in OS/X Leopard system header */
  274 #     endif
  275 #    endif
  276 #    if defined(WIN32) && !defined(__GNUWIN32__)
  277       typedef __int64                int64;    /**< int64 is a 64-bit signed integer type */
  278       typedef unsigned __int64       uint64;   /**< uint64 is a 64-bit unsigned integer type */
  279 #    elif __APPLE__
  280 #     ifndef _UINT64
  281 #      define _UINT64                          /**< Avoid conflict with typedef in OS/X Leopard system header */
  282        typedef long long              int64;   /**< int64 is a 64-bit signed integer type */    // these are what's expected in MacOS/X land, in both
  283        typedef unsigned long long     uint64;  /**< uint64 is a 64-bit unsigned integer type */ // 32-bit and 64-bit flavors.  C'est la vie, non?
  284 #     endif
  285 #    elif defined(MUSCLE_64_BIT_PLATFORM)
  286       typedef long                   int64;    /**< int64 is a 64-bit signed integer type */
  287       typedef unsigned long          uint64;   /**< uint64 is a 64-bit unsigned integer type */
  288 #    else
  289       typedef long long              int64;    /**< int64 is a 64-bit signed integer type */
  290       typedef unsigned long long     uint64;   /**< uint64 is a 64-bit unsigned integer type */
  291 #    endif
  292 #   else
  293      // If stdint.h is available, we might as well use it
  294      typedef  int8_t    int8; /**< int8 is an 8-bit signed integer type */
  295      typedef uint8_t   uint8; /**< uint8 is an 8-bit unsigned integer type */
  296      typedef  int16_t  int16; /**< int16 is a 16-bit signed integer type */
  297      typedef uint16_t uint16; /**< uint16 is a 16-bit unsigned integer type */
  298      typedef  int32_t  int32; /**< int32 is a 32-bit signed integer type */
  299      typedef uint32_t uint32; /**< uint32 is a 32-bit unsigned integer type */
  300      typedef  int64_t  int64; /**< int64 is a 64-bit signed integer type */
  301      typedef uint64_t uint64; /**< uint64 is a 64-bit unsigned integer type */
  302 #   endif
  303      typedef int32 c_status_t; /**< For C programs: This type indicates an expected value of either CB_NO_ERROR/CB_OK on success, or another value (often CB_ERROR) on failure. */
  304 #   if defined(__cplusplus)
  305      namespace muscle {
  306         /** This class represents a return-value from a function or method that indicates success or failure.
  307           * It's implemented as a class instead of as a typedef or enum so that the compiler can provide 
  308           * stricter compile-time type-checking and better error-reporting functionality.  When a function 
  309           * wants to indicate that it succeeded, it should return B_NO_ERROR (or B_OK, which is a synonym).
  310           * If the function wants to indicate that it failed, it can return B_ERROR to indicate a 
  311           * general/undescribed failure, or one of the other B_SOMETHING values (as listed in 
  312           * support/MuscleSupport.h), or it can return B_ERROR("Some Error Description") if it wants to 
  313           * describe its failure using an ad-hoc human-readable string.  In that last case, make sure the 
  314           * string you pass in to B_ERROR is a compile-time constant, or in some other way * will remain 
  315           * valid indefinitely, since the status_t object will keep only a (const char *) pointer to the 
  316           * string, and therefore depends on that pointed-to char-array remaining valid.
  317           */
  318         class status_t
  319         {
  320         public:
  321            /** Default-constructor.  Creates a status_t representing success. */
  322            MUSCLE_CONSTEXPR status_t() : _desc(NULL) {/* empty */}
  323 
  324            /** Explicit Constructor.
  325              * param desc An optional human-description of the error.  If passed in as NULL (the default), the status will represent success.
  326              * @note The (desc) string is NOT copied: only the pointer is retained, so any non-NULL (desc) argument 
  327              *       should be a compile-time-constant string!
  328              */
  329            MUSCLE_CONSTEXPR explicit status_t(const char * desc) : _desc(desc) {/* empty */}
  330 
  331            /** Copy constructor
  332              * @param rhs the status_t to make this object a copy of
  333              */
  334            MUSCLE_CONSTEXPR status_t(const status_t & rhs) : _desc(rhs._desc) {/* empty */}
  335 
  336            /** Comparison operator.  Returns true iff this object is equivalent to (rhs).
  337              * @param rhs the status_t to compare against
  338              */
  339            MUSCLE_CONSTEXPR bool operator ==(const status_t & rhs) const
  340            {
  341               return _desc ? ((rhs._desc)&&(strcmp(_desc, rhs._desc) == 0)) : (rhs._desc == NULL);
  342            }
  343 
  344            /** Comparison operator.  Returns true iff this object has a different value than (rhs)
  345              * @param rhs the status_t to compare against
  346              */
  347            MUSCLE_CONSTEXPR bool operator !=(const status_t & rhs) const {return !(*this==rhs);}
  348 
  349            /** This operator returns B_NO_ERROR iff both inputs are equal to B_NO_ERROR,
  350              * otherwise it returns one of the non-B_NO_ERROR values.  This operator is
  351              * useful for aggregating a unordered series of operations together and 
  352              * checking the aggregate result (e.g. status_t ret = a() | b() | c() | d())
  353              * @param rhs the second status_t to test this status_t against
  354              * @note Due to the way the | operator is defined in C++, the order of evaluations
  355              *       of the operations in the series in unspecified.  Also, no short-circuiting
  356              *       is performed; all operands will be evaluated regardless of their values.
  357              */
  358            MUSCLE_CONSTEXPR status_t operator | (const status_t & rhs) const {return ((rhs.IsError())&&(!IsError())) ? rhs : *this;}
  359 
  360            /** Sets this object equal to ((*this)|rhs).
  361              * @param rhs the second status_t to test this status_t against
  362              */
  363            status_t & operator |= (const status_t & rhs) {*this = ((*this)|rhs); return *this;}
  364 
  365            /** Returns "OK" if this status_t indicates success; otherwise returns the human-readable description 
  366              * of the error this status_t indicates.
  367              */
  368            MUSCLE_CONSTEXPR const char * GetDescription() const {return IsOK() ? "OK" : _desc;}
  369 
  370            /** Convenience method -- a synonym for GetDescription() */
  371            MUSCLE_CONSTEXPR const char * operator()() const {return GetDescription();}
  372 
  373            /** Convenience method:  Returns true this object represents an ok/non-error status */
  374            MUSCLE_CONSTEXPR bool IsOK() const {return (_desc == NULL);}
  375 
  376            /** Convenience method:  Returns true iff this object represents an ok/non-error status
  377              * @param writeErrorTo If this object represents an error, the error will be copied into (writeErrorTo)
  378              * @note this allows for e.g. status_t ret; if ((func1().IsOK(ret))&&(func2().IsOK(ret))) {....} else return ret;
  379              */
  380            bool IsOK(status_t & writeErrorTo) const 
  381            {
  382               const bool isOK = IsOK();
  383               if (isOK == false) writeErrorTo = *this;
  384               return isOK;
  385            }
  386 
  387            /** Convenience method:  Returns true iff this object represents an error-status */
  388            MUSCLE_CONSTEXPR bool IsError() const {return (_desc != NULL);}
  389 
  390            /** Convenience method:  Returns true iff this object represents an error-status
  391              * @param writeErrorTo If this object represents an error, the error will be copied into (writeErrorTo)
  392              * @note this allows for e.g. status_t ret; if ((func1().IsError(ret))||(func2().IsError(ret))) return ret;
  393              */
  394            bool IsError(status_t & writeErrorTo) const 
  395            {
  396               const bool isError = IsError();
  397               if (isError) writeErrorTo = *this;
  398               return isError;
  399            }
  400 
  401            /** Returns a status_t with the given error-string.  (Added to allow e.g. B_ERROR("The Reason Why") syntax)
  402              * @param desc the error-string the returned status_t should have.  Should be a compile-time constant.
  403              * @note if this is called on a status_t that has a NULL error-string, then (desc) will be ignored and
  404              *       the returned status_t will also have a NULL error string.  That is to avoid doing the wrong thing
  405              *       if someone tries to do a B_NO_ERROR("Yay") or etc.
  406              */ 
  407            MUSCLE_CONSTEXPR status_t operator()(const char * desc) const {return status_t(_desc?desc:NULL);}
  408 
  409         private:
  410            const char * _desc;  // If non-NULL, we represent an error
  411         };
  412 
  413         // Basic/general status_t return codes
  414         const status_t B_NO_ERROR;       ///< This value is returned by a function or method that succeeded
  415         const status_t B_OK;             ///< This value is a synonym for B_NO_ERROR
  416         const status_t B_ERROR("Error"); ///< "Error": This value is returned by a function or method that errored out in a non-descript fashion
  417 #       define B_ERRNO B_ERROR(strerror(GetErrno())) ///< Macro for return a B_ERROR with the current errno-string as its string-value
  418 #       define B_ERRNUM(errnum) ((errnum==0)?B_NO_ERROR:B_ERROR(strerror(errnum))) ///< Macro for converting an errno-style return value (0==success, negative==error_value) result into a status_t
  419 
  420         // Some more-specific status_t return codes (for convenience, and to minimize the likelihood of 
  421         // differently-phrased error strings for common types of reasons-for-failure)
  422         extern const status_t B_OUT_OF_MEMORY;  ///< "Out of Memory"  - we tried to allocate memory from the heap and got denied
  423         extern const status_t B_UNIMPLEMENTED;  ///< "Unimplemented"  - function is not implemented (for this OS?)
  424         extern const status_t B_ACCESS_DENIED;  ///< "Access Denied"  - we aren't allowed to do the thing we tried to do
  425         extern const status_t B_DATA_NOT_FOUND; ///< "Data not Found" - we couldn't find the data we were looking for
  426         extern const status_t B_FILE_NOT_FOUND; ///< "File not Found" - we couldn't find the file we were looking for
  427         extern const status_t B_BAD_ARGUMENT;   ///< "Bad Argument"   - one of the passed-in arguments didn't make sense
  428         extern const status_t B_BAD_DATA;       ///< "Bad Data"       - data we were trying to use was malformed
  429         extern const status_t B_BAD_OBJECT;     ///< "Bad Object"     - the object the method was called on is not in a usable state for this operation
  430         extern const status_t B_TIMED_OUT;      ///< "Timed Out"      - the operation took too long, so we gave up
  431         extern const status_t B_IO_ERROR;       ///< "I/O Error"      - an I/O operation failed
  432         extern const status_t B_LOCK_FAILED;    ///< "Lock Failed"    - an attempt to lock a shared resource (e.g. a Mutex) failed.
  433         extern const status_t B_TYPE_MISMATCH;  ///< "Type Mismatch"  - tried to fit a square block into a round hole
  434         extern const status_t B_ZLIB_ERROR;     ///< "ZLib Error"     - a zlib library-function reported an error
  435         extern const status_t B_SSL_ERROR;      ///< "SSL Error"      - an OpenSSL library-function reported an error
  436         extern const status_t B_LOGIC_ERROR;    ///< "Logic Error"    - internal logic has gone wrong somehow (bug?)
  437      };
  438 #   endif  /* defined(__cplusplus) */
  439 #  endif  /* !MUSCLE_TYPES_PREDEFINED */
  440 # endif  /* !__ATHEOS__*/
  441 #endif  /* __BEOS__ || __HAIKU__ */
  442 
  443 #if defined(__cplusplus) && !defined(MUSCLE_AVOID_CPLUSPLUS11)
  444 // Let's try to catch any type-size errors at compile-time if we can
  445 static_assert(sizeof(int8)   == 1, "sizeof(int8) != 1");
  446 static_assert(sizeof(uint8)  == 1, "sizeof(uint8) != 1");
  447 static_assert(sizeof(int16)  == 2, "sizeof(int16) != 2");
  448 static_assert(sizeof(uint16) == 2, "sizeof(uint16) != 2");
  449 static_assert(sizeof(int32)  == 4, "sizeof(int32) != 4");
  450 static_assert(sizeof(uint32) == 4, "sizeof(uint32) != 4");
  451 static_assert(sizeof(int64)  == 8, "sizeof(int64) != 8");
  452 static_assert(sizeof(uint64) == 8, "sizeof(uint64) != 8");
  453 static_assert(sizeof(float)  == 4, "sizeof(float) != 4");
  454 static_assert(sizeof(float)  == 4, "sizeof(float) != 4");
  455 static_assert(sizeof(double) == 8, "sizeof(double) != 8");
  456 static_assert(sizeof(double) == 8, "sizeof(double) != 8");
  457 #endif
  458 
  459 #ifdef MUSCLE_AVOID_STDINT
  460 /** Ugly platform-neutral macros for problematic sprintf()-format-strings */
  461 # if defined(MUSCLE_64_BIT_PLATFORM)
  462 #  define  INT32_FORMAT_SPEC_NOPERCENT "i"  /**< format-specifier string to pass in to printf() for an int32, without the percent sign */
  463 #  define UINT32_FORMAT_SPEC_NOPERCENT "u"  /**< format-specifier string to pass in to printf() for a uint32, without the percent sign */
  464 #  define XINT32_FORMAT_SPEC_NOPERCENT "x"  /**< format-specifier string to pass in to printf() for an int32 or uint32 that you want printed in hexadecimal, without the percent sign */
  465 #  ifdef __APPLE__
  466 #   define  INT64_FORMAT_SPEC_NOPERCENT "lli"  /**< format-specifier string to pass in to printf() for an int64, without the percent sign */
  467 #   define UINT64_FORMAT_SPEC_NOPERCENT "llu"  /**< format-specifier string to pass in to printf() for a uint64, without the percent sign */
  468 #   define XINT64_FORMAT_SPEC_NOPERCENT "llx"  /**< format-specifier string to pass in to printf() for an int64 or uint64 that you want printed in hexadecimal, without the percent sign */
  469 #  elif defined(_MSC_VER) || defined(__MINGW64__)
  470 #   define  INT64_FORMAT_SPEC_NOPERCENT "I64i"  /**< format-specifier string to pass in to printf() for an int64, without the percent sign */
  471 #   define UINT64_FORMAT_SPEC_NOPERCENT "I64u"  /**< format-specifier string to pass in to printf() for a uint64, without the percent sign */
  472 #   define XINT64_FORMAT_SPEC_NOPERCENT "I64x"  /**< format-specifier string to pass in to printf() for an int64 or uint64 that you want printed in hexadecimal, without the percent sign */
  473 #  else
  474 #   define  INT64_FORMAT_SPEC_NOPERCENT "li"  /**< format-specifier string to pass in to printf() for an int64, without the percent sign */
  475 #   define UINT64_FORMAT_SPEC_NOPERCENT "lu"  /**< format-specifier string to pass in to printf() for a uint64, without the percent sign */
  476 #   define XINT64_FORMAT_SPEC_NOPERCENT "lx"  /**< format-specifier string to pass in to printf() for an int64 or uint64 that you want printed in hexadecimal, without the percent sign */
  477 #  endif
  478 # else
  479 #  define  INT32_FORMAT_SPEC_NOPERCENT "li"  /**< format-specifier string to pass in to printf() for an int32, without the percent sign */
  480 #  define UINT32_FORMAT_SPEC_NOPERCENT "lu"  /**< format-specifier string to pass in to printf() for a uint32, without the percent sign */
  481 #  define XINT32_FORMAT_SPEC_NOPERCENT "lx"  /**< format-specifier string to pass in to printf() for an int32 or uint32 that you want printed in hexadecimal, without the percent sign */
  482 #  if defined(_MSC_VER) || defined(__MINGW32__)
  483 #   define  INT64_FORMAT_SPEC_NOPERCENT "I64i"  /**< format-specifier string to pass in to printf() for an int64, without the percent sign */
  484 #   define UINT64_FORMAT_SPEC_NOPERCENT "I64u"  /**< format-specifier string to pass in to printf() for a uint64, without the percent sign */
  485 #   define XINT64_FORMAT_SPEC_NOPERCENT "I64x"  /**< format-specifier string to pass in to printf() for an int64 or uint64 that you want printed in hexadecimal, without the percent sign */
  486 #  elif (defined(__BEOS__) && !defined(__HAIKU__)) || defined(__MWERKS__) || defined(__BORLANDC__)
  487 #   define  INT64_FORMAT_SPEC_NOPERCENT "Li"  /**< format-specifier string to pass in to printf() for an int64, without the percent sign */
  488 #   define UINT64_FORMAT_SPEC_NOPERCENT "Lu"  /**< format-specifier string to pass in to printf() for a uint64, without the percent sign */
  489 #   define XINT64_FORMAT_SPEC_NOPERCENT "Lx"  /**< format-specifier string to pass in to printf() for an int64 or uint64 that you want printed in hexadecimal, without the percent sign */
  490 #  else
  491 #   define  INT64_FORMAT_SPEC_NOPERCENT "lli"  /**< format-specifier string to pass in to printf() for an int64, without the percent sign */
  492 #   define UINT64_FORMAT_SPEC_NOPERCENT "llu"  /**< format-specifier string to pass in to printf() for a uint64, without the percent sign */
  493 #   define XINT64_FORMAT_SPEC_NOPERCENT "llx"  /**< format-specifier string to pass in to printf() for an int64 or uint64 that you want printed in hexadecimal, without the percent sign */
  494 #  endif
  495 # endif
  496 #else
  497 // This version just uses the macros provided in inttypes.h
  498 #  define  INT32_FORMAT_SPEC_NOPERCENT PRIi32 /**< format-specifier string to pass in to printf() for an int32, without the percent sign */
  499 #  define UINT32_FORMAT_SPEC_NOPERCENT PRIu32 /**< format-specifier string to pass in to printf() for a uint32, without the percent sign */
  500 #  define XINT32_FORMAT_SPEC_NOPERCENT PRIx32 /**< format-specifier string to pass in to printf() for an int32 or uint32 that you want printed in hexadecimal, without the percent sign */
  501 #  define  INT64_FORMAT_SPEC_NOPERCENT PRIi64 /**< format-specifier string to pass in to printf() for a  int64, without the percent sign */
  502 #  define UINT64_FORMAT_SPEC_NOPERCENT PRIu64 /**< format-specifier string to pass in to printf() for a uint64, without the percent sign */
  503 #  define XINT64_FORMAT_SPEC_NOPERCENT PRIx64 /**< format-specifier string to pass in to printf() for an int64 or uint64 that you want printed in hexadecimal, without the percent sign */
  504 #endif
  505 
  506 #define  INT32_FORMAT_SPEC "%"  INT32_FORMAT_SPEC_NOPERCENT /**< format-specifier string to pass in to printf() for an int32, including the percent sign */
  507 #define UINT32_FORMAT_SPEC "%" UINT32_FORMAT_SPEC_NOPERCENT /**< format-specifier string to pass in to printf() for a uint32, including the percent sign */
  508 #define XINT32_FORMAT_SPEC "%" XINT32_FORMAT_SPEC_NOPERCENT /**< format-specifier string to pass in to printf() for an int32 or uint32 that you want printed in hexadecimal, including the percent sign */
  509 
  510 #define  INT64_FORMAT_SPEC "%"  INT64_FORMAT_SPEC_NOPERCENT /**< format-specifier string to pass in to printf() for an int64, including the percent sign */
  511 #define UINT64_FORMAT_SPEC "%" UINT64_FORMAT_SPEC_NOPERCENT /**< format-specifier string to pass in to printf() for a uint64, including the percent sign */
  512 #define XINT64_FORMAT_SPEC "%" XINT64_FORMAT_SPEC_NOPERCENT /**< format-specifier string to pass in to printf() for an int64 or uint64 that you want printed in hexadecimal, including the percent sign */
  513 
  514 /** Macro that returns a uint32 word out of the four ASCII characters in the supplied char array.  Used primarily to create 'what'-codes for Message objects (e.g. MAKETYPE("!Pc0") returns 558916400) */
  515 #define MAKETYPE(x) ((((unsigned long)(x[0])) << 24) | \
  516                      (((unsigned long)(x[1])) << 16) | \
  517                      (((unsigned long)(x[2])) <<  8) | \
  518                      (((unsigned long)(x[3])) <<  0))
  519 
  520 #if !defined(__BEOS__) && !defined(__HAIKU__)
  521 /** Be-style message-field type codes.
  522   * I've calculated the integer equivalents for these codes
  523   * because g++ generates warnings about four-byte
  524   * constants when compiling under Linux --jaf
  525   */
  526 enum {
  527    B_ANY_TYPE     = 1095653716, /**< 'ANYT' = wild card                                   */
  528    B_BOOL_TYPE    = 1112493900, /**< 'BOOL' = boolean (1 byte per bool)                   */
  529    B_DOUBLE_TYPE  = 1145195589, /**< 'DBLE' = double-precision float (8 bytes per double) */
  530    B_FLOAT_TYPE   = 1179406164, /**< 'FLOT' = single-precision float (4 bytes per float)  */
  531    B_INT64_TYPE   = 1280069191, /**< 'LLNG' = long long integer (8 bytes per int)         */
  532    B_INT32_TYPE   = 1280265799, /**< 'LONG' = long integer (4 bytes per int)              */
  533    B_INT16_TYPE   = 1397248596, /**< 'SHRT' = short integer (2 bytes per int)             */
  534    B_INT8_TYPE    = 1113150533, /**< 'BYTE' = byte integer (1 byte per int)               */
  535    B_MESSAGE_TYPE = 1297303367, /**< 'MSGG' = sub Message objects (reference counted)     */
  536    B_POINTER_TYPE = 1347310674, /**< 'PNTR' = pointers (will not be flattened)            */
  537    B_POINT_TYPE   = 1112559188, /**< 'BPNT' = Point objects (each Point has two floats)   */
  538    B_RECT_TYPE    = 1380270932, /**< 'RECT' = Rect objects (each Rect has four floats)    */
  539    B_STRING_TYPE  = 1129534546, /**< 'CSTR' = String objects (variable length)            */
  540    B_OBJECT_TYPE  = 1330664530, /**< 'OPTR' = Flattened user objects (obsolete)           */
  541    B_RAW_TYPE     = 1380013908, /**< 'RAWT' = Raw data (variable number of bytes)         */
  542    B_MIME_TYPE    = 1296649541, /**< 'MIME' = MIME strings (obsolete)                     */
  543    B_BITCHORD_TYPE= 1112818504  /**< 'BTCH' = BitChord type                               */
  544 };
  545 #endif
  546 
  547 /** This one isn't defined by BeOS, so we have to enumerate it separately.                */
  548 enum {
  549    B_TAG_TYPE     = 1297367367  /**< 'MTAG' = new for v2.00; for in-mem-only tags         */
  550 };
  551 
  552 /** This constant is used in various places to mean 'as much as you want'.  Its value is ((uint32)-1), aka ((2^32)-1) */
  553 #define MUSCLE_NO_LIMIT ((uint32)-1)
  554 
  555 #ifdef __cplusplus
  556 
  557 /** A handy little method to swap the bytes of any int-style datatype around */
  558 template<typename T> inline T muscleSwapBytes(T swapMe)
  559 {
  560    union {T _iWide; uint8 _i8[sizeof(T)];} u1, u2;
  561    u1._iWide = swapMe;
  562 
  563    int i = 0;
  564    int numBytes = sizeof(T);
  565    while(numBytes>0) u2._i8[i++] = u1._i8[--numBytes];
  566    return u2._iWide;
  567 }
  568 
  569 /* This template safely copies a value in from an untyped byte buffer to a typed value, and returns the typed value.  */
  570 template<typename T> inline T muscleCopyIn(const void * source) {T dest; memcpy(&dest, source, sizeof(dest)); return dest;}
  571 
  572 /* This template safely copies a value in from an untyped byte buffer to a typed value.  */
  573 template<typename T> inline void muscleCopyIn(T & dest, const void * source) {memcpy(&dest, source, sizeof(dest));}
  574 
  575 /** This template safely copies a value in from a typed value to an untyped byte buffer.  */
  576 template<typename T> inline void muscleCopyOut(void * dest, const T & source) {memcpy(dest, &source, sizeof(source));}
  577 
  578 /** This macro should be used instead of "newnothrow T[count]".  It works the
  579   * same, except that it hacks around an ugly bug in gcc 3.x where newnothrow
  580   * would return ((T*)0x4) on memory failure instead of NULL.
  581   * See http://gcc.gnu.org/bugzilla/show_bug.cgi?id=10300
  582   */
  583 #if __GNUC__ == 3
  584 template <typename T> inline T * broken_gcc_newnothrow_array(size_t count)
  585 {
  586    T * ret = newnothrow T[count];
  587    return (ret <= (T *)(sizeof(void *))) ? NULL : ret;
  588 }
  589 # define newnothrow_array(T, count) broken_gcc_newnothrow_array<T>(count)  /**< workaround wrapper for broken newnothrow T[count] under gcc 3.x */
  590 #else
  591 # define newnothrow_array(T, count) newnothrow T[count]                    /**< workaround wrapper for broken newnothrow T[count] under gcc 3.x */
  592 #endif
  593 
  594 /** This function returns a reference to a read-only, default-constructed
  595   * static object of type T.  There will be exactly one of these objects
  596   * present per instantiated type, per process.
  597   */
  598 template <typename T> const T & GetDefaultObjectForType()
  599 {
  600    static T _defaultObject;
  601    return _defaultObject;
  602 }
  603 
  604 /** This function returns a reference to a read/write, default-constructed
  605   * static object of type T.  There will be exactly one of these objects
  606   * present per instantiated type, per process.
  607   *
  608   * Note that this object is different from the one returned by
  609   * GetDefaultObjectForType(); the difference (other than there being
  610   * possibly two separate objects) is that this one can be written to,
  611   * whereas GetDefaultObjectForType()'s object must always be in its default state.
  612   */
  613 template <typename T> T & GetGlobalObjectForType()
  614 {
  615    static T _defaultObject;
  616    return _defaultObject;
  617 }
  618 
  619 #if __GNUC__ >= 4
  620 # define MUSCLE_MAY_ALIAS __attribute__((__may_alias__))
  621 #else
  622 # define MUSCLE_MAY_ALIAS
  623 #endif
  624 
  625 #ifndef MUSCLE_AVOID_CPLUSPLUS11
  626 
  627 /** Returns the smaller of the two arguments */
  628 template<typename T> MUSCLE_CONSTEXPR T muscleMin(T arg1, T arg2) {return (arg1<arg2) ? arg1 : arg2;}
  629 
  630 /** Returns the smallest of all of the arguments */
  631 template<typename T1, typename ...T2> MUSCLE_CONSTEXPR T1 muscleMin(T1 arg1, T2... args) {return muscleMin(arg1, muscleMin(args...));}
  632 
  633 /** Returns the larger of the two arguments */
  634 template<typename T> MUSCLE_CONSTEXPR T muscleMax(T arg1, T arg2) {return (arg1>arg2) ? arg1 : arg2;}
  635 
  636 /** Returns the largest of all of the arguments */
  637 template<typename T1, typename ...T2> MUSCLE_CONSTEXPR T1 muscleMax(T1 arg1, T2... args) {return muscleMax(arg1, muscleMax(args...));}
  638 
  639 #else
  640 
  641 /** Returns the smaller of the two arguments */
  642 template<typename T> inline MUSCLE_CONSTEXPR T muscleMin(T p1, T p2) {return (p1 < p2) ? p1 : p2;}
  643 
  644 /** Returns the smallest of the three arguments */
  645 template<typename T> inline MUSCLE_CONSTEXPR T muscleMin(T p1, T p2, T p3) {return muscleMin(p3, muscleMin(p1, p2));}
  646 
  647 /** Returns the smallest of the four arguments */
  648 template<typename T> inline MUSCLE_CONSTEXPR T muscleMin(T p1, T p2, T p3, T p4) {return muscleMin(p3, p4, muscleMin(p1, p2));}
  649 
  650 /** Returns the smallest of the five arguments */
  651 template<typename T> inline MUSCLE_CONSTEXPR T muscleMin(T p1, T p2, T p3, T p4, T p5) {return muscleMin(p3, p4, p5, muscleMin(p1, p2));}
  652 
  653 /** Returns the larger of the two arguments */
  654 template<typename T> inline MUSCLE_CONSTEXPR T muscleMax(T p1, T p2) {return (p1 < p2) ? p2 : p1;}
  655 
  656 /** Returns the largest of the three arguments */
  657 template<typename T> inline MUSCLE_CONSTEXPR T muscleMax(T p1, T p2, T p3) {return muscleMax(p3, muscleMax(p1, p2));}
  658 
  659 /** Returns the largest of the four arguments */
  660 template<typename T> inline MUSCLE_CONSTEXPR T muscleMax(T p1, T p2, T p3, T p4) {return muscleMax(p3, p4, muscleMax(p1, p2));}
  661 
  662 /** Returns the largest of the five arguments */
  663 template<typename T> inline MUSCLE_CONSTEXPR T muscleMax(T p1, T p2, T p3, T p4, T p5) {return muscleMax(p3, p4, p5, muscleMax(p1, p2));}
  664 
  665 #endif
  666 
  667 #if defined(__GNUC__) && (__GNUC__ <= 3) && !defined(MUSCLE_AVOID_AUTOCHOOSE_SWAP)
  668 # define MUSCLE_AVOID_AUTOCHOOSE_SWAP
  669 #endif
  670 
  671 #ifdef MUSCLE_AVOID_AUTOCHOOSE_SWAP
  672 
  673 /** Swaps the two arguments.  (Primitive version, used only for old compilers like G++ 3.x that can't handle the SFINAE)
  674   * @param t1 First item to swap.  After this method returns, it will be equal to the old value of t2.
  675   * @param t2 Second item to swap.  After this method returns, it will be equal to the old value of t1.
  676   */
  677 template<typename T> inline void muscleSwap(T & t1, T & t2) {T t=t1; t1 = t2; t2 = t;}
  678 
  679 #else
  680 
  681 # ifndef DOXYGEN_SHOULD_IGNORE_THIS
  682 namespace ugly_swapcontents_method_sfinae_implementation
  683 {
  684    // This code was adapted from the example code at http://www.martinecker.com/wiki/index.php?title=Detecting_the_Existence_of_Member_Functions_at_Compile-Time
  685    // It is used by the muscleSwap() function (below) to automatically call SwapContents() if such a method
  686    // is available, otherwise muscleSwap() will use a naive copy-to-temporary-object technique.
  687 
  688    typedef char yes;
  689    typedef char (&no)[2];
  690    template <typename T, void (T::*f)(T&)> struct test_swapcontents_wrapper {};
  691 
  692    // via SFINAE only one of these overloads will be considered
  693    template <typename T> yes swapcontents_tester(test_swapcontents_wrapper<T, &T::SwapContents>*);
  694    template <typename T> no  swapcontents_tester(...);
  695 
  696    template <typename T> struct test_swapcontents_impl {static const bool value = sizeof(swapcontents_tester<T>(0)) == sizeof(yes);};
  697 
  698    template <class T> struct has_swapcontents_method : test_swapcontents_impl<T> {};
  699    template <bool Condition, typename TrueResult, typename FalseResult> struct if_;
  700    template <typename TrueResult, typename FalseResult> struct if_<true,  TrueResult, FalseResult> {typedef TrueResult  result;};
  701    template <typename TrueResult, typename FalseResult> struct if_<false, TrueResult, FalseResult> {typedef FalseResult result;};
  702 
  703    template<typename T> class PODSwapper
  704    {
  705    public:
  706       PODSwapper(T & t1, T & t2)
  707       {
  708          if (&t1 == &t2) return;
  709 
  710 #ifndef MUSCLE_AVOID_CPLUSPLUS11
  711          T tmp(std::move(t1));
  712          t1 = std::move(t2); 
  713          t2 = std::move(tmp);
  714 #else
  715          T tmp = t1;
  716          t1 = t2;
  717          t2 = tmp;
  718 #endif
  719       }
  720    };
  721 
  722    template<typename T> class SwapContentsSwapper
  723    {
  724    public:
  725       SwapContentsSwapper(T & t1, T & t2) {if (&t1 != &t2) t1.SwapContents(t2);}
  726    };
  727 
  728    template<typename ItemType> class AutoChooseSwapperHelper
  729    {
  730    public:
  731       typedef typename if_<test_swapcontents_impl<ItemType>::value, SwapContentsSwapper<ItemType>, PODSwapper<ItemType> >::result Type;
  732    };
  733 }
  734 # endif
  735 
  736 /** Swaps the two arguments.
  737   * @param t1 First item to swap.  After this method returns, it will be equal to the old value of t2.
  738   * @param t2 Second item to swap.  After this method returns, it will be equal to the old value of t1.
  739   */
  740 template<typename T> inline void muscleSwap(T & t1, T & t2) {typename ugly_swapcontents_method_sfinae_implementation::AutoChooseSwapperHelper<T>::Type swapper(t1,t2);}
  741 
  742 #endif
  743 
  744 /** Returns true iff (i) is a valid index into array (a)
  745   * @param i An index value
  746   * @param theArray an array of any type
  747   * @returns True iff i is non-negative AND less than ARRAYITEMS(theArray))
  748   */
  749 template<typename T, int size> inline MUSCLE_CONSTEXPR bool muscleArrayIndexIsValid(int i, T (&theArray)[size]) {return ((theArray)&&(((unsigned int)i) < size));}
  750 
  751 /** Convenience method for setting all items in the specified one-dimensional array to their default-constructed state (i.e. zero)
  752   * @param theArray an array of any type
  753   * @param t The object to set every item in the array equal to.  Defaults to a default-constructed object of the appropriate type.
  754   */
  755 template<typename T, int size1> inline void muscleClearArray(T (&theArray)[size1], const T & t = GetDefaultObjectForType<T>()) {for (int i=0; i<size1; i++) theArray[i] = t;}
  756 
  757 /** Convenience method for setting all items in the specified two-dimensional array to their default-constructed state (i.e. zero)
  758   * @param theArray an array of any type
  759   * @param t The object to set every item in the array equal to.  Defaults to a default-constructed object of the appropriate type.
  760   */
  761 template<typename T, int size1, int size2> inline void muscleClearArray(T (&theArray)[size1][size2], const T & t = GetDefaultObjectForType<T>()) {for (int i=0; i<size1; i++) for (int j=0; j<size2; j++) theArray[i][j] = t;}
  762 
  763 /** Convenience method for setting all items in the specified three-dimensional array to their default-constructed state (i.e. zero)
  764   * @param theArray an array of any type
  765   * @param t The object to set every item in the array equal to.  Defaults to a default-constructed object of the appropriate type.
  766   */
  767 template<typename T, int size1, int size2, int size3> inline void muscleClearArray(T (&theArray)[size1][size2][size3], const T & t = GetDefaultObjectForType<T>()) {for (int i=0; i<size1; i++) for (int j=0; j<size2; j++) for (int k=0; k<size3; k++) theArray[i][j][k] = t;}
  768 
  769 /** Returns the value nearest to (v) that is still in the range [lo, hi].
  770   * @param v A value
  771   * @param lo a minimum value
  772   * @param hi a maximum value
  773   * @returns The value in the range [lo, hi] that is closest to (v).
  774   */
  775 template<typename T> inline MUSCLE_CONSTEXPR T muscleClamp(T v, T lo, T hi) {return (v < lo) ? lo : ((v > hi) ? hi : v);}
  776 
  777 /** Returns true iff (v) is in the range [lo,hi].
  778   * @param v A value
  779   * @param lo A minimum value
  780   * @param hi A maximum value
  781   * @returns true iff (v >= lo) and (v <= hi)
  782   */
  783 template<typename T> inline MUSCLE_CONSTEXPR bool muscleInRange(T v, T lo, T hi) {return ((v >= lo)&&(v <= hi));}
  784 
  785 /** Returns -1 if arg1 is larger, or 1 if arg2 is larger, or 0 if they are equal.
  786   * @param arg1 First item to compare
  787   * @param arg2 Second item to compare
  788   * @returns -1 if (arg1<arg2), or 1 if (arg2<arg1), or 0 otherwise.
  789   */
  790 template<typename T> inline MUSCLE_CONSTEXPR int muscleCompare(const T & arg1, const T & arg2) {return (arg2<arg1) ? 1 : ((arg1<arg2) ? -1 : 0);}
  791 
  792 /** Returns the absolute value of (arg) */
  793 template<typename T> inline MUSCLE_CONSTEXPR T muscleAbs(T arg) {return (arg<0)?(-arg):arg;}
  794 
  795 /** Rounds the given float to the nearest integer value. */
  796 inline MUSCLE_CONSTEXPR int muscleRintf(float f) {return (f>=0.0f) ? ((int)(f+0.5f)) : -((int)((-f)+0.5f));}
  797 
  798 /** Returns -1 if the value is less than zero, +1 if it is greater than zero, or 0 otherwise. */
  799 template<typename T> inline MUSCLE_CONSTEXPR int muscleSgn(T arg) {return (arg<0)?-1:((arg>0)?1:0);}
  800 
  801 #endif  /* __cplusplus */
  802 
  803 #if defined(__cplusplus) && (_MSC_VER >= 1400)
  804 /** For MSVC, we provide CRT-friendly versions of these functions to avoid security warnings */
  805 # define muscleSprintf  sprintf_s  /* Ooh, template magic! */
  806 # define muscleSnprintf sprintf_s  /* Yes, sprintf_s is correct here! (this version is usable when template magic isn't possible) -jaf */
  807 # define muscleStrcpy   strcpy_s   /* Ooh, template magic! */
  808 static inline char * muscleStrncpy(char * to, const char * from, size_t maxLen) {(void) strcpy_s(to, maxLen, from); return to;}
  809 static inline FILE * muscleFopen(const char * path, const char * mode) {FILE * fp; return (fopen_s(&fp, path, mode) == 0) ? fp : NULL;}
  810 #else
  811 /** Other OS's can use the usual functions instead. */
  812 # define muscleSprintf  sprintf   /**< On Windows, this expands to sprintf_s to avoid security warnings; on other OS's it expands to plain old sprintf */
  813 # define muscleSnprintf snprintf  /**< On Windows, this expands to snprintf_s to avoid security warnings; on other OS's it expands to plain old snprintf */
  814 # define muscleStrcpy   strcpy    /**< On Windows, this expands to strcpy_s to avoid security warnings; on other OS's it expands to plain old strcpy */
  815 # define muscleStrncpy  strncpy   /**< On Windows, this expands to strncpy_s to avoid security warnings; on other OS's it expands to plain old strncpy */
  816 # define muscleFopen    fopen     /**< On Windows, this expands to fopen_s to avoid security warnings; on other OS's it expands to plain old fopen */
  817 #endif
  818 
  819 #if !defined(__BEOS__) && !defined(__HAIKU__)
  820 
  821 /*
  822  * Copyright(c) 1983,   1989
  823  *    The Regents of the University of California.  All rights reserved.
  824  *
  825  * Redistribution and use in source and binary forms, with or without
  826  * modification, are permitted provided that the following conditions
  827  * are met:
  828  * 1. Redistributions of source code must retain the above copyright
  829  *    notice, this list of conditions and the following disclaimer.
  830  * 2. Redistributions in binary form must reproduce the above copyright
  831  *    notice, this list of conditions and the following disclaimer in the
  832  *    documentation and/or other materials provided with the distribution.
  833  * 3. All advertising materials mentioning features or use of this software
  834  *    must display the following acknowledgement:
  835  *      This product includes software developed by the University of
  836  *      California, Berkeley and its contributors.
  837  * 4. Neither the name of the University nor the names of its contributors
  838  *    may be used to endorse or promote products derived from this software
  839  *    without specific prior written permission.
  840  *
  841  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  842  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  843  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  844  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  845  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  846  * DAMAGES(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  847  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  848  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  849  * LIABILITY, OR TORT(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  850  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  851  * SUCH DAMAGE.
  852  */
  853 
  854 /*
  855  *      from nameser.h  8.1 (Berkeley) 6/2/93
  856  */
  857 
  858 #ifndef BYTE_ORDER
  859   #if (BSD >= 199103)
  860     #include <machine/endian.h>
  861   #else
  862     #if defined(linux) || defined(__linux__)
  863       #include <endian.h>
  864     #elif defined( __APPLE__ )
  865       #include <machine/endian.h>
  866     #elif defined( __EMSCRIPTEN__ )
  867       #include <endian.h>
  868     #else
  869       #define LITTLE_ENDIAN   1234    /**< least-significant byte first (vax, pc) */
  870       #define BIG_ENDIAN      4321    /**< most-significant byte first (IBM, net) */
  871 
  872       #if defined(vax) || defined(ns32000) || defined(sun386) || defined(i386) || \
  873               defined(__i386) || defined(__ia64) || \
  874               defined(MIPSEL) || defined(_MIPSEL) || defined(BIT_ZERO_ON_RIGHT) || \
  875               defined(__alpha__) || defined(__alpha) || defined(__CYGWIN__) || \
  876               defined(_M_IX86) || defined(_M_AMD64) || defined(__GNUWIN32__) || defined(__LITTLEENDIAN__) || \
  877               defined(__MINGW32__) || defined(__MINGW64__) || \
  878               defined(_M_ARM) || defined(_M_ARM64) || \
  879               (defined(__Lynx__) && defined(__x86__))
  880         #define BYTE_ORDER      LITTLE_ENDIAN
  881       #endif
  882 
  883       #if defined(__POWERPC__) || defined(sel) || defined(pyr) || defined(mc68000) || defined(sparc) || \
  884           defined(__sparc) || \
  885           defined(is68k) || defined(tahoe) || defined(ibm032) || defined(ibm370) || \
  886           defined(MIPSEB) || defined(_MIPSEB) || defined(_IBMR2) || defined(DGUX) ||\
  887           defined(apollo) || defined(__convex__) || defined(_CRAY) || \
  888           defined(__hppa) || defined(__hp9000) || \
  889           defined(__hp9000s300) || defined(__hp9000s700) || \
  890           defined(__hp3000s900) || defined(MPE) || \
  891           defined(BIT_ZERO_ON_LEFT) || defined(m68k) || \
  892               (defined(__Lynx__) && \
  893               (defined(__68k__) || defined(__sparc__) || defined(__powerpc__)))
  894         #define BYTE_ORDER      BIG_ENDIAN
  895       #endif
  896     #endif /* linux */
  897   #endif /* BSD */
  898 #endif /* BYTE_ORDER */
  899 
  900 #if !defined(BYTE_ORDER) || (BYTE_ORDER != BIG_ENDIAN && BYTE_ORDER != LITTLE_ENDIAN)
  901         /*
  902          * you must determine what the correct bit order is for
  903          * your compiler - the next line is an intentional error
  904          * which will force your compiles to bomb until you fix
  905          * the above macros.
  906          */
  907 #       error "Undefined or invalid BYTE_ORDER -- you will need to modify MuscleSupport.h to correct this";
  908 #endif
  909 
  910 /* End replacement code from Sun/University of California */
  911 
  912 /***********************************************************************************************
  913  * FLOAT_TROUBLE COMMENT
  914  *
  915  * NOTE: The *_FLOAT_* macros listed below are obsolete and must no longer be used, because
  916  * they are inherently unsafe.  The reason is that on certain processors (read x86), the
  917  * byte-swapped representation of certain floating point and double values can end up
  918  * representing an invalid value (NaN)... in which case the x86 FPU feels free to munge
  919  * some of the bits into a "standard NaN" bit-pattern... causing silent data corruption
  920  * when the value is later swapped back into its native form and again interpreted as a
  921  * float or double value.  Instead, you need to change your code to use the *_IFLOAT_*
  922  * macros, which work similarly except that the externalized value is safely stored as
  923  * a int32 (for floats) or a int64 (for doubles).  --Jeremy 1/8/2007
  924  **********************************************************************************************/
  925 
  926 #ifndef DOXYGEN_SHOULD_IGNORE_THIS
  927 # define B_HOST_TO_BENDIAN_FLOAT(arg) B_HOST_TO_BENDIAN_FLOAT_was_removed_use_B_HOST_TO_BENDIAN_IFLOAT_instead___See_the_FLOAT_TROUBLE_comment_in_support_MuscleSupport_h_for_details_
  928 # define B_HOST_TO_LENDIAN_FLOAT(arg) B_HOST_TO_LENDIAN_FLOAT_was_removed_use_B_HOST_TO_LENDIAN_IFLOAT_instead___See_the_FLOAT_TROUBLE_comment_in_support_MuscleSupport_h_for_details_
  929 # define B_BENDIAN_TO_HOST_FLOAT(arg) B_BENDIAN_TO_HOST_FLOAT_was_removed_use_B_BENDIAN_TO_HOST_IFLOAT_instead___See_the_FLOAT_TROUBLE_comment_in_support_MuscleSupport_h_for_details_
  930 # define B_LENDIAN_TO_HOST_FLOAT(arg) B_LENDIAN_TO_HOST_FLOAT_was_removed_use_B_LENDIAN_TO_HOST_IFLOAT_instead___See_the_FLOAT_TROUBLE_comment_in_support_MuscleSupport_h_for_details_
  931 # define B_SWAP_FLOAT(arg)            B_SWAP_FLOAT_was_removed___See_the_FLOAT_TROUBLE_comment_in_support_MuscleSupport_h_for_details.
  932 #endif
  933 
  934 /***********************************************************************************************
  935  * DOUBLE_TROUBLE COMMENT
  936  *
  937  * NOTE: The *_DOUBLE_* macros listed below are obsolete and must no longer be used, because
  938  * they are inherently unsafe.  The reason is that on certain processors (read x86), the
  939  * byte-swapped representation of certain floating point and double values can end up
  940  * representing an invalid value (NaN)... in which case the x86 FPU feels free to munge
  941  * some of the bits into a "standard NaN" bit-pattern... causing silent data corruption
  942  * when the value is later swapped back into its native form and again interpreted as a
  943  * float or double value.  Instead, you need to change your code to use the *_IDOUBLE_*
  944  * macros, which work similarly except that the externalized value is safely stored as
  945  * a int32 (for floats) or a int64 (for doubles).  --Jeremy 1/8/2007
  946  **********************************************************************************************/
  947 
  948 #ifndef DOXYGEN_SHOULD_IGNORE_THIS
  949 # define B_HOST_TO_BENDIAN_DOUBLE(arg) B_HOST_TO_BENDIAN_DOUBLE_was_removed_use_B_HOST_TO_BENDIAN_IDOUBLE_instead___See_the_DOUBLE_TROUBLE_comment_in_support_MuscleSupport_h_for_details_
  950 # define B_HOST_TO_LENDIAN_DOUBLE(arg) B_HOST_TO_LENDIAN_DOUBLE_was_removed_use_B_HOST_TO_LENDIAN_IDOUBLE_instead___See_the_DOUBLE_TROUBLE_comment_in_support_MuscleSupport_h_for_details_
  951 # define B_BENDIAN_TO_HOST_DOUBLE(arg) B_BENDIAN_TO_HOST_DOUBLE_was_removed_use_B_BENDIAN_TO_HOST_IDOUBLE_instead___See_the_DOUBLE_TROUBLE_comment_in_support_MuscleSupport_h_for_details_
  952 # define B_LENDIAN_TO_HOST_DOUBLE(arg) B_LENDIAN_TO_HOST_DOUBLE_was_removed_use_B_LENDIAN_TO_HOST_IDOUBLE_instead___See_the_DOUBLE_TROUBLE_comment_in_support_MuscleSupport_h_for_details_
  953 # define B_SWAP_DOUBLE(arg)            B_SWAP_DOUBLE_was_removed___See_the_DOUBLE_TROUBLE_comment_in_support_MuscleSupport_h_for_details_
  954 #endif
  955 
  956 # if defined(MUSCLE_USE_POWERPC_INLINE_ASSEMBLY)
  957 static inline uint16 MusclePowerPCSwapInt16(uint16 val)
  958 {
  959    uint16 a;
  960    uint16 * addr = &a;
  961    __asm__ ("sthbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr));
  962    return a;
  963 }
  964 static inline uint32 MusclePowerPCSwapInt32(uint32 val)
  965 {
  966    uint32 a;
  967    uint32 * addr = &a;
  968    __asm__ ("stwbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr));
  969    return a;
  970 }
  971 static inline uint64 MusclePowerPCSwapInt64(uint64 val)
  972 {
  973    return ((uint64)(MusclePowerPCSwapInt32((uint32)((val>>32)&0xFFFFFFFF))))|(((uint64)(MusclePowerPCSwapInt32((uint32)(val&0xFFFFFFFF))))<<32);
  974 }
  975 #  define B_SWAP_INT64(arg)    MusclePowerPCSwapInt64((uint64)(arg))  /**< Given a uint64, returns its endian-swapped equivalent */
  976 #  define B_SWAP_INT32(arg)    MusclePowerPCSwapInt32((uint32)(arg))  /**< Given a uint32, returns its endian-swapped equivalent */
  977 #  define B_SWAP_INT16(arg)    MusclePowerPCSwapInt16((uint16)(arg))  /**< Given a uint16, returns its endian-swapped equivalent */
  978 # elif defined(MUSCLE_USE_MSVC_SWAP_FUNCTIONS)
  979 #  define B_SWAP_INT64(arg)    _byteswap_uint64((uint64)(arg))        /**< Given a uint64, returns its endian-swapped equivalent */
  980 #  define B_SWAP_INT32(arg)    _byteswap_ulong((uint32)(arg))         /**< Given a uint32, returns its endian-swapped equivalent */
  981 #  define B_SWAP_INT16(arg)    _byteswap_ushort((uint16)(arg))        /**< Given a uint16, returns its endian-swapped equivalent */
  982 # elif defined(MUSCLE_USE_X86_INLINE_ASSEMBLY)
  983 static inline uint16 MuscleX86SwapInt16(uint16 val)
  984 {
  985 #ifdef _MSC_VER
  986    __asm {
  987       mov ax, val;
  988       xchg al, ah;
  989       mov val, ax;
  990    };
  991 #elif defined(MUSCLE_64_BIT_PLATFORM)
  992    __asm__ ("xchgb %h0, %b0" : "+Q" (val));
  993 #else
  994    __asm__ ("xchgb %h0, %b0" : "+q" (val));
  995 #endif
  996    return val;
  997 }
  998 static inline uint32 MuscleX86SwapInt32(uint32 val)
  999 {
 1000 #ifdef _MSC_VER
 1001    __asm {
 1002       mov eax, val;
 1003       bswap eax;
 1004       mov val, eax;
 1005    };
 1006 #else
 1007    __asm__ ("bswap %0" : "+r" (val));
 1008 #endif
 1009    return val;
 1010 }
 1011 static inline uint64 MuscleX86SwapInt64(uint64 val)
 1012 {
 1013 #ifdef _MSC_VER
 1014    __asm {
 1015       mov eax, DWORD PTR val;
 1016       mov edx, DWORD PTR val + 4;
 1017       bswap eax;
 1018       bswap edx;
 1019       mov DWORD PTR val, edx;
 1020       mov DWORD PTR val + 4, eax;
 1021    };
 1022    return val;
 1023 #elif defined(MUSCLE_64_BIT_PLATFORM)
 1024    __asm__ ("bswap %0" : "=r" (val) : "0" (val));
 1025    return val;
 1026 #else
 1027    return ((uint64)(MuscleX86SwapInt32((uint32)((val>>32)&0xFFFFFFFF))))|(((uint64)(MuscleX86SwapInt32((uint32)(val&0xFFFFFFFF))))<<32);
 1028 #endif
 1029 }
 1030 #  define B_SWAP_INT64(arg)    MuscleX86SwapInt64((uint64)(arg))
 1031 #  define B_SWAP_INT32(arg)    MuscleX86SwapInt32((uint32)(arg))
 1032 #  define B_SWAP_INT16(arg)    MuscleX86SwapInt16((uint16)(arg))
 1033 # else
 1034 
 1035 // No assembly language available... so we'll use inline C
 1036 
 1037 # if defined(__cplusplus)
 1038 #  define MUSCLE_INLINE inline          /**< Expands to "inline" for C++ code, or to "static inline" for C code */
 1039 # else
 1040 #  define MUSCLE_INLINE static inline   /**< Expands to "inline" for C++ code, or to "static inline" for C code */
 1041 # endif
 1042 
 1043 /** Given a 64-bit integer, returns its endian-swapped counterpart */
 1044 MUSCLE_INLINE int64 B_SWAP_INT64(int64 arg)
 1045 {
 1046    union {int64 _i64; uint8 _i8[8];} u1, u2;
 1047    u1._i64   = arg;
 1048    u2._i8[0] = u1._i8[7];
 1049    u2._i8[1] = u1._i8[6];
 1050    u2._i8[2] = u1._i8[5];
 1051    u2._i8[3] = u1._i8[4];
 1052    u2._i8[4] = u1._i8[3];
 1053    u2._i8[5] = u1._i8[2];
 1054    u2._i8[6] = u1._i8[1];
 1055    u2._i8[7] = u1._i8[0];
 1056    return u2._i64;
 1057 }
 1058 
 1059 /** Given a 32-bit integer, returns its endian-swapped counterpart */
 1060 MUSCLE_INLINE int32 B_SWAP_INT32(int32 arg)
 1061 {
 1062    union {int32 _i32; uint8 _i8[4];} u1, u2;
 1063    u1._i32   = arg;
 1064    u2._i8[0] = u1._i8[3];
 1065    u2._i8[1] = u1._i8[2];
 1066    u2._i8[2] = u1._i8[1];
 1067    u2._i8[3] = u1._i8[0];
 1068    return u2._i32;
 1069 }  
 1070 
 1071 /** Given a 16-bit integer, returns its endian-swapped counterpart */
 1072 MUSCLE_INLINE int16 B_SWAP_INT16(int16 arg)
 1073 {
 1074    union {int16 _i16; uint8 _i8[2];} u1, u2;
 1075    u1._i16   = arg;
 1076    u2._i8[0] = u1._i8[1];
 1077    u2._i8[1] = u1._i8[0];
 1078    return u2._i16;
 1079 }
 1080 
 1081 # endif
 1082 # if BYTE_ORDER == LITTLE_ENDIAN
 1083 #  define B_HOST_IS_LENDIAN 1                              /**< Set to 1 if native CPU is little-endian; set to 0 if native CPU is big-endian. */
 1084 #  define B_HOST_IS_BENDIAN 0                              /**< Set to 1 if native CPU is big-endian; set to 0 if native CPU is little-endian. */
 1085 #  define B_HOST_TO_LENDIAN_INT64(arg)  ((uint64)(arg))    /**< Given a uint64 or int64 in native-endian format, returns its equivalent little-endian value. */
 1086 #  define B_HOST_TO_LENDIAN_INT32(arg)  ((uint32)(arg))    /**< Given a uint32 or int32 in native-endian format, returns its equivalent little-endian value. */
 1087 #  define B_HOST_TO_LENDIAN_INT16(arg)  ((uint16)(arg))    /**< Given a uint16 or int16 in native-endian format, returns its equivalent little-endian value. */
 1088 #  define B_HOST_TO_BENDIAN_INT64(arg)  B_SWAP_INT64(arg)  /**< Given a uint64 or int64 in native-endian format, returns its equivalent big-endian value. */
 1089 #  define B_HOST_TO_BENDIAN_INT32(arg)  B_SWAP_INT32(arg)  /**< Given a uint32 or int32 in native-endian format, returns its equivalent big-endian value. */
 1090 #  define B_HOST_TO_BENDIAN_INT16(arg)  B_SWAP_INT16(arg)  /**< Given a uint16 or int16 in native-endian format, returns its equivalent big-endian value. */
 1091 #  define B_LENDIAN_TO_HOST_INT64(arg)  ((uint64)(arg))    /**< Given a uint64 or int64 in little-endian format, returns its equivalent native-endian value. */
 1092 #  define B_LENDIAN_TO_HOST_INT32(arg)  ((uint32)(arg))    /**< Given a uint32 or int32 in little-endian format, returns its equivalent native-endian value. */
 1093 #  define B_LENDIAN_TO_HOST_INT16(arg)  ((uint16)(arg))    /**< Given a uint16 or int16 in little-endian format, returns its equivalent native-endian value. */
 1094 #  define B_BENDIAN_TO_HOST_INT64(arg)  B_SWAP_INT64(arg)  /**< Given a uint64 or int64 in big-endian format, returns its equivalent native-endian value. */
 1095 #  define B_BENDIAN_TO_HOST_INT32(arg)  B_SWAP_INT32(arg)  /**< Given a uint32 or int32 in big-endian format, returns its equivalent native-endian value. */
 1096 #  define B_BENDIAN_TO_HOST_INT16(arg)  B_SWAP_INT16(arg)  /**< Given a uint16 or int16 in big-endian format, returns its equivalent native-endian value. */
 1097 # else
 1098 #  define B_HOST_IS_LENDIAN 0                              /**< Set to 1 if native CPU is little-endian; set to 0 if native CPU is big-endian. */
 1099 #  define B_HOST_IS_BENDIAN 1                              /**< Set to 1 if native CPU is big-endian; set to 0 if native CPU is little-endian. */
 1100 #  define B_HOST_TO_LENDIAN_INT64(arg)  B_SWAP_INT64(arg)  /**< Given a uint64 or int64 in native-endian format, returns its equivalent little-endian value. */
 1101 #  define B_HOST_TO_LENDIAN_INT32(arg)  B_SWAP_INT32(arg)  /**< Given a uint32 or int32 in native-endian format, returns its equivalent little-endian value. */
 1102 #  define B_HOST_TO_LENDIAN_INT16(arg)  B_SWAP_INT16(arg)  /**< Given a uint16 or int16 in native-endian format, returns its equivalent little-endian value. */
 1103 #  define B_HOST_TO_BENDIAN_INT64(arg)  ((uint64)(arg))    /**< Given a uint64 or int64 in native-endian format, returns its equivalent big-endian value. */
 1104 #  define B_HOST_TO_BENDIAN_INT32(arg)  ((uint32)(arg))    /**< Given a uint32 or int32 in native-endian format, returns its equivalent big-endian value. */
 1105 #  define B_HOST_TO_BENDIAN_INT16(arg)  ((uint16)(arg))    /**< Given a uint16 or int16 in native-endian format, returns its equivalent big-endian value. */
 1106 #  define B_LENDIAN_TO_HOST_INT64(arg)  B_SWAP_INT64(arg)  /**< Given a uint64 or int64 in little-endian format, returns its equivalent native-endian value. */
 1107 #  define B_LENDIAN_TO_HOST_INT32(arg)  B_SWAP_INT32(arg)  /**< Given a uint32 or int32 in little-endian format, returns its equivalent native-endian value. */
 1108 #  define B_LENDIAN_TO_HOST_INT16(arg)  B_SWAP_INT16(arg)  /**< Given a uint16 or int16 in little-endian format, returns its equivalent native-endian value. */
 1109 #  define B_BENDIAN_TO_HOST_INT64(arg)  ((uint64)(arg))    /**< Given a uint64 or int64 in big-endian format, returns its equivalent native-endian value. */
 1110 #  define B_BENDIAN_TO_HOST_INT32(arg)  ((uint32)(arg))    /**< Given a uint32 or int32 in big-endian format, returns its equivalent native-endian value. */
 1111 #  define B_BENDIAN_TO_HOST_INT16(arg)  ((uint16)(arg))    /**< Given a uint16 or int16 in big-endian format, returns its equivalent native-endian value. */
 1112 # endif
 1113 #endif /* !__BEOS__ && !__HAIKU__*/
 1114 
 1115 /** Newer, architecture-safe float and double endian-ness swappers.  Note that for these
 1116   * macros, the externalized value is expected to be stored in an int32 (for floats) or
 1117   * in an int64 (for doubles).  See the FLOAT_TROUBLE and DOUBLE_TROUBLE comments elsewhere
 1118   * in this header file for an explanation as to why.  --Jeremy 01/08/2007
 1119   */
 1120 
 1121 /** Safely reinterprets a floating-point value to store its bit-pattern in a uint32.  (Note that mere casting isn't safe under x86!)
 1122   * @param arg The 32-bit floating point value to reinterpret
 1123   * @returns a uint32 whose 32-bit bit-pattern is the same as the bits in (arg)
 1124   */
 1125 static inline uint32 B_REINTERPRET_FLOAT_AS_INT32(float arg)   {uint32 r; memcpy(&r, &arg, sizeof(r)); return r;}
 1126 
 1127 /** Reinterprets the bit-pattern of a uint32 as a floating-point value.  (Note that mere casting isn't safe under x86!)
 1128   * @param arg The uint32 value whose contents are known to represent the bits of a 32-bit floating-point value.
 1129   * @returns The original floating point value that (arg) is equivalent to.
 1130   */
 1131 static inline float  B_REINTERPRET_INT32_AS_FLOAT(uint32 arg)  {float  r; memcpy(&r, &arg, sizeof(r)); return r;}
 1132 
 1133 /** Safely reinterprets a double-precision floating-point value to store its bit-pattern in a uint64.  (Note that mere casting isn't safe under x86!)
 1134   * @param arg The 64-bit floating point value to reinterpret
 1135   * @returns a uint64 whose 64-bit bit-pattern is the same as the bits in (arg)
 1136   */
 1137 static inline uint64 B_REINTERPRET_DOUBLE_AS_INT64(double arg) {uint64 r; memcpy(&r, &arg, sizeof(r)); return r;}
 1138 
 1139 /** Reinterprets the bit-pattern of a uint64 as a double-precision floating-point value.  (Note that mere casting isn't safe under x86!)
 1140   * @param arg The uint64 value whose contents are known to represent the bits of a 64-bit floating-point value.
 1141   * @returns The original double-precision point value that (arg) is equivalent to.
 1142   */
 1143 static inline double B_REINTERPRET_INT64_AS_DOUBLE(uint64 arg) {double r; memcpy(&r, &arg, sizeof(r)); return r;}
 1144 
 1145 /** Given a 32-bit floating point value in native-endian form, returns a 32-bit integer contains the floating-point value's bits in big-endian format. */
 1146 #define B_HOST_TO_BENDIAN_IFLOAT(arg)  B_HOST_TO_BENDIAN_INT32(B_REINTERPRET_FLOAT_AS_INT32(arg))
 1147 
 1148 /** Given a 32-bit integer representing a floating point value in big-endian format, returns the floating point value in native-endian form. */ 
 1149 #define B_BENDIAN_TO_HOST_IFLOAT(arg)  B_REINTERPRET_INT32_AS_FLOAT(B_BENDIAN_TO_HOST_INT32(arg))
 1150 
 1151 /** Given a 32-bit floating point value in native-endian form, returns a 32-bit integer contains the floating-point value's bits in little-endian format. */
 1152 #define B_HOST_TO_LENDIAN_IFLOAT(arg)  B_HOST_TO_LENDIAN_INT32(B_REINTERPRET_FLOAT_AS_INT32(arg))
 1153 
 1154 /** Given a 32-bit integer representing a floating point value in little-endian format, returns the floating point value in native-endian form. */ 
 1155 #define B_LENDIAN_TO_HOST_IFLOAT(arg)  B_REINTERPRET_INT32_AS_FLOAT(B_LENDIAN_TO_HOST_INT32(arg))
 1156 
 1157 /** Given a 64-bit floating point value in native-endian form, returns a 64-bit integer contains the floating-point value's bits in big-endian format. */
 1158 #define B_HOST_TO_BENDIAN_IDOUBLE(arg) B_HOST_TO_BENDIAN_INT64(B_REINTERPRET_DOUBLE_AS_INT64(arg))
 1159 
 1160 /** Given a 64-bit integer representing a floating point value in big-endian format, returns the double-precision floating point value in native-endian form. */ 
 1161 #define B_BENDIAN_TO_HOST_IDOUBLE(arg) B_REINTERPRET_INT64_AS_DOUBLE(B_BENDIAN_TO_HOST_INT64(arg))
 1162 
 1163 /** Given a 64-bit floating point value in native-endian format, returns a 64-bit integer contains the floating-point value's bits in little-endian format. */
 1164 #define B_HOST_TO_LENDIAN_IDOUBLE(arg) B_HOST_TO_LENDIAN_INT64(B_REINTERPRET_DOUBLE_AS_INT64(arg))
 1165 
 1166 /** Given a 64-bit integer representing a floating point value in little-endian format, returns the double-precision floating point value in native-endian form. */ 
 1167 #define B_LENDIAN_TO_HOST_IDOUBLE(arg) B_REINTERPRET_INT64_AS_DOUBLE(B_LENDIAN_TO_HOST_INT64(arg))
 1168 
 1169 /* Macro to turn a type code into a string representation.
 1170  * (typecode) is the type code to get the string for
 1171  * (buf) is a (char *) to hold the output string; it must be >= 5 bytes long.
 1172  */
 1173 static inline void MakePrettyTypeCodeString(uint32 typecode, char *buf)
 1174 {
 1175    uint32 i;  // keep separate, for C compatibility
 1176    uint32 bigEndian = B_HOST_TO_BENDIAN_INT32(typecode);
 1177 
 1178    memcpy(buf, (const char *)&bigEndian, sizeof(bigEndian));
 1179    buf[sizeof(bigEndian)] = '\0';
 1180    for (i=0; i<sizeof(bigEndian); i++) if ((buf[i]<' ')||(buf[i]>'~')) buf[i] = '?';
 1181 }
 1182 
 1183 #ifdef WIN32
 1184 # include <winsock2.h>  // this will bring in windows.h for us
 1185 #endif
 1186 
 1187 #ifdef MUSCLE_AVOID_STDINT
 1188 # ifdef _MSC_VER
 1189 typedef UINT_PTR uintptr;   // Use these under MSVC so that the compiler
 1190 typedef INT_PTR  ptrdiff;   // doesn't give spurious warnings in /Wp64 mode
 1191 # else
 1192 #  if defined(MUSCLE_64_BIT_PLATFORM)
 1193 typedef uint64 uintptr;  /**< uintptr is an unsigned integer type that is guaranteed to be able to hold a pointer value for the native CPU, without any data loss */
 1194 typedef int64 ptrdiff;   /**< ptrdiff is a signed integer type that is guaranteed to be able to hold the difference between two pointer values for the native CPU, without any data loss */
 1195 #  else
 1196 typedef uint32 uintptr;  /**< uintptr is an unsigned integer type that is guaranteed to be able to hold a pointer value for the native CPU, without any data loss */
 1197 typedef int32 ptrdiff;   /**< ptrdiff is a signed integer type that is guaranteed to be able to hold the difference between two pointer values for the native CPU, without any data loss */
 1198 #  endif
 1199 # endif
 1200 #else
 1201 typedef uintptr_t uintptr; /**< uintptr is an unsigned integer type that is guaranteed to be able to hold a pointer value for the native CPU, without any data loss */
 1202 typedef ptrdiff_t ptrdiff; /**< ptrdiff is a signed integer type that is guaranteed to be able to hold the difference between two pointer values for the native CPU, without any data loss */
 1203 #endif
 1204 
 1205 #ifdef __cplusplus
 1206 # include "syslog/SysLog.h"  /* for LogTime() */
 1207 #endif  /* __cplusplus */
 1208 
 1209 /** Platform-neutral interface to reading errno -- returns WSAGetLastError() on Windows, or errno on other OS's */
 1210 static inline int GetErrno()
 1211 {
 1212 #ifdef WIN32
 1213    return WSAGetLastError();
 1214 #else
 1215    return errno;
 1216 #endif
 1217 }
 1218 
 1219 /** Platform-neutral interface to setting errno -- calls WSASetLastError() on Windows, or sets errno on other OS's
 1220   * @param e The new value to set the errno variable to
 1221   */
 1222 static inline void SetErrno(int e)
 1223 {
 1224 #ifdef WIN32
 1225    WSASetLastError(e);
 1226 #else
 1227    errno = e;
 1228 #endif
 1229 }
 1230 
 1231 /** Checks errno and returns true iff the last I/O operation
 1232   * failed because it would have had to block otherwise.
 1233   * NOTE:  Returns int so that it will compile even in C environments where no bool type is defined.
 1234   */
 1235 static inline int PreviousOperationWouldBlock()
 1236 {
 1237    const int e = GetErrno();
 1238 #ifdef WIN32
 1239    return (e == WSAEWOULDBLOCK);
 1240 #else
 1241    return (e == EWOULDBLOCK);
 1242 #endif
 1243 }
 1244 
 1245 /** Checks errno and returns true iff the last I/O operation
 1246   * failed because it was interrupted by a signal or etc.
 1247   * NOTE:  Returns int so that it will compile even in C environments where no bool type is defined.
 1248   */
 1249 static inline int PreviousOperationWasInterrupted()
 1250 {
 1251    const int e = GetErrno();
 1252 #ifdef WIN32
 1253    return (e == WSAEINTR);
 1254 #else
 1255    return (e == EINTR);
 1256 #endif
 1257 }
 1258 
 1259 /** Checks errno and returns true iff the last I/O operation
 1260   * failed because of a transient condition which wasn't fatal to the socket.
 1261   * NOTE:  Returns int so that it will compile even in C environments where no bool type is defined.
 1262   */
 1263 static inline int PreviousOperationHadTransientFailure()
 1264 {
 1265    const int e = GetErrno();
 1266 #ifdef WIN32
 1267    return ((e == WSAEINTR)||(e == WSAENOBUFS));
 1268 #else
 1269    return ((e == EINTR)||(e == ENOBUFS));
 1270 #endif
 1271 }
 1272 
 1273 /** This function applies semi-standard logic to convert the return value
 1274   * of a system I/O call and (errno) into a proper MUSCLE-standard return value.
 1275   * (A MUSCLE-standard return value's semantics are:  Negative on error,
 1276   * otherwise the return value is the number of bytes that were transferred)
 1277   * @param origRet The return value of the original system call (e.g. to read()/write()/send()/recv())
 1278   * @param maxSize The maximum number of bytes that the system call was permitted to send during that call.
 1279   * @param blocking True iff the socket/file descriptor is in blocking I/O mode.  (Type is int for C compatibility -- it's really a boolean parameter)
 1280   * @returns The system call's return value equivalent in MUSCLE return value semantics.
 1281   */
 1282 static inline int32 ConvertReturnValueToMuscleSemantics(long origRet, uint32 maxSize, int blocking)
 1283 {
 1284    int32 retForBlocking = ((origRet > 0)||(maxSize == 0)) ? (int32)origRet : -1;
 1285    return blocking ? retForBlocking : ((origRet<0)&&((PreviousOperationWouldBlock())||(PreviousOperationHadTransientFailure()))) ? 0 : retForBlocking;
 1286 }
 1287 
 1288 #ifdef __cplusplus
 1289 namespace muscle {
 1290 class DataNode;  // FogBugz #9816 tweakage
 1291 #endif
 1292 
 1293 #ifndef DOXYGEN_SHOULD_IGNORE_THIS
 1294 // forward declarations
 1295 extern void Crash();
 1296 extern void ExitWithoutCleanup(int);
 1297 #endif
 1298 
 1299 #if MUSCLE_TRACE_CHECKPOINTS > 0
 1300 
 1301 /** Exposed as an implementation detail.  Please ignore! */
 1302 extern volatile uint32 * _muscleTraceValues;
 1303 
 1304 /** Exposed as an implementation detail.  Please ignore! */
 1305 extern uint32 _muscleNextTraceValueIndex;
 1306 
 1307 /** Sets the location of the trace-checkpoints array to store trace checkpoints into.
 1308   * @param location A pointer to an array of at least (MUSCLE_TRACE_CHECKPOINTS) uint32s, or NULL.
 1309   *                 If NULL (or if this function is never called), the default array will be used.
 1310   */
 1311 void SetTraceValuesLocation(volatile uint32 * location);
 1312 
 1313 /** Set this process's current trace value to (v).  This can be used as a primitive debugging tool, to determine
 1314   * where this process was last seen executing -- useful for determining where the process is spinning at.
 1315   * @note this function is a no-op if MUSCLE_TRACE_CHECKPOINTS is not defined to a value greater than zero.
 1316   */
 1317 static inline void StoreTraceValue(uint32 v)
 1318 {
 1319    _muscleTraceValues[_muscleNextTraceValueIndex] = v;  /* store the current value */
 1320    _muscleNextTraceValueIndex                     = (_muscleNextTraceValueIndex+1)%MUSCLE_TRACE_CHECKPOINTS; /* move the pointer */
 1321    _muscleTraceValues[_muscleNextTraceValueIndex] = MUSCLE_NO_LIMIT;  /* mark the next position with a special tag to show that it's next */
 1322 }
 1323 
 1324 /** Returns a pointer to the first value in the trace-values array. */
 1325 static inline const volatile uint32 * GetTraceValues() {return _muscleTraceValues;}
 1326 
 1327 /** A macro for automatically setting a trace checkpoint value based on current code location.
 1328   * The value will be the two characters of the function or file name, left-shifted by 16 bits,
 1329   * and then OR'd together with the current line number.  This should give the debugging person a
 1330   * fairly good clue as to where the checkpoint was located, while still being very cheap to implement.
 1331   *
 1332   * @note This function will be a no-op unless MUSCLE_TRACE_CHECKPOINTS is defined to be greater than zero.
 1333   */
 1334 #if defined(__GNUC__)
 1335 #define TCHECKPOINT                                   \
 1336 {                                                     \
 1337    const char * d = __FUNCTION__;                     \
 1338    StoreTraceValue((d[0]<<24)|(d[1]<<16)|(__LINE__)); \
 1339 }
 1340 #else
 1341 #define TCHECKPOINT                                   \
 1342 {                                                     \
 1343    const char * d = __FILE__;                         \
 1344    StoreTraceValue((d[0]<<24)|(d[1]<<16)|(__LINE__)); \
 1345 }
 1346 #endif
 1347 
 1348 #else
 1349 /* no-op implementations for when we aren't using the trace facility */
 1350 static inline void SetTraceValuesLocation(volatile uint32 * location) {(void) location;}  /* named param is necessary for C compatibility */
 1351 static inline void StoreTraceValue(uint32 v) {(void) v;}  /* named param is necessary for C compatibility */
 1352 
 1353 /** A macro for automatically setting a trace checkpoint value based on current code location.
 1354   * The value will be the two characters of the function or file name, left-shifted by 16 bits,
 1355   * and then OR'd together with the current line number.  This should give the debugging person a
 1356   * fairly good clue as to where the checkpoint was located, while still being very cheap to implement.
 1357   *
 1358   * @note This function will be a no-op unless MUSCLE_TRACE_CHECKPOINTS is defined to be greater than zero.
 1359   */
 1360 #define TCHECKPOINT {/* empty */}
 1361 #endif
 1362 
 1363 #ifdef __cplusplus
 1364 
 1365 /** This templated class is used as a "comparison callback" for sorting items in a Queue or Hashtable.
 1366   * For many types, this default CompareFunctor template will do the job, but you also have the option of specifying
 1367   * a different custom CompareFunctor for times when you want to sort in ways other than simply using the
 1368   * less than and equals operators of the ItemType type.
 1369   */
 1370 template <typename ItemType> class CompareFunctor
 1371 {
 1372 public:
 1373    /**
 1374     *  This is the signature of the type of callback function that you must pass
 1375     *  into the Sort() method.  This function should work like strcmp(), returning
 1376     *  a negative value if (item1) is less than item2, or zero if the items are
 1377     *  equal, or a positive value if (item1) is greater than item2.
 1378     *  The default implementation simply calls the muscleCompare() function.
 1379     *  @param item1 The first item
 1380     *  @param item2 The second item
 1381     *  @param cookie A user-defined value that was passed in to the Sort() method.
 1382     *  @return A value indicating which item is "larger", as defined above.
 1383     */
 1384    int Compare(const ItemType & item1, const ItemType & item2, void * cookie) const {(void) cookie; return muscleCompare(item1, item2);}
 1385 };
 1386 
 1387 /** Same as above, but used for pointers instead of direct items */
 1388 template <typename ItemType> class CompareFunctor<ItemType *>
 1389 {
 1390 public:
 1391    int Compare(const ItemType * item1, const ItemType * item2, void * cookie) const {return CompareFunctor<ItemType>().Compare(*item1, *item2, cookie);}
 1392 };
 1393 
 1394 /** For void pointers, we just compare the pointer values, since they can't be de-referenced. */
 1395 template<> class CompareFunctor<void *>
 1396 {
 1397 public:
 1398    int Compare(void * s1, void * s2, void * /*cookie*/) const {return muscleCompare(s1, s2);}
 1399 };
 1400 
 1401 /** We assume that (const char *)'s should always be compared using strcmp(). */
 1402 template<> class CompareFunctor<const char *>
 1403 {
 1404 public:
 1405    int Compare(const char * s1, const char * s2, void * /*cookie*/) const {return strcmp(s1, s2);}
 1406 };
 1407 
 1408 /** We assume that (const char *)'s should always be compared using strcmp(). */
 1409 template<> class CompareFunctor<char *>
 1410 {
 1411 public:
 1412    int Compare(char * s1, char * s2, void * /*cookie*/) const {return strcmp(s1, s2);}
 1413 };
 1414 
 1415 /** For cases where you really do want to just use a pointer as the key, instead
 1416   * of cleverly trying to dereference the object it points to and sorting on that, you can specify this.
 1417   */
 1418 template <typename PointerType> class PointerCompareFunctor
 1419 {
 1420 public:
 1421    int Compare(PointerType s1, PointerType s2, void * /*cookie*/) const {return muscleCompare(s1, s2);}
 1422 };
 1423 
 1424 /** Hash function for arbitrary data.  Note that the current implementation of this function
 1425   * is MurmurHash2/Aligned, taken from http://murmurhash.googlepages.com/ and used as public domain code.
 1426   * Thanks to Austin Appleby for the cool algorithm!
 1427   * @param key Pointer to the data to hash
 1428   * @param numBytes Number of bytes to hash start at (key)
 1429   * @param seed An arbitrary number that affects the output values.  Defaults to zero.
 1430   * @returns a 32-bit hash value corresponding to the hashed data.
 1431   */
 1432 uint32 CalculateHashCode(const void * key, uint32 numBytes, uint32 seed = 0);
 1433 
 1434 /** Same as HashCode(), but this version produces a 64-bit result.
 1435   * This code is also part of MurmurHash2, written by Austin Appleby
 1436   * @param key Pointer to the data to hash
 1437   * @param numBytes Number of bytes to hash start at (key)
 1438   * @param seed An arbitrary number that affects the output values.  Defaults to zero.
 1439   * @returns a 32-bit hash value corresponding to the hashed data.
 1440   */
 1441 uint64 CalculateHashCode64(const void * key, unsigned int numBytes, unsigned int seed = 0);
 1442 
 1443 /** Convenience method; returns the hash code of the given data item.  Any POD type will do. 
 1444   * @param val The value to calculate a hashcode for
 1445   * @returns a hash code.
 1446   */
 1447 template<typename T> inline uint32 CalculateHashCode(const T & val) {return CalculateHashCode(&val, sizeof(val));}
 1448 
 1449 /** Convenience method; returns the 64-bit hash code of the given data item.  Any POD type will do. 
 1450   * @param val The value to calculate a hashcode for
 1451   * @returns a hash code.
 1452   */
 1453 template<typename T> inline uint64 CalculateHashCode64(const T & val) {return CalculateHashCode64(&val, sizeof(val));}
 1454 
 1455 /** This is a convenience function that will read through the passed-in byte
 1456   * buffer and create a 32-bit checksum corresponding to its contents.
 1457   * Note:  As of MUSCLE 5.22, this function is merely a synonym for CalculateHashCode().
 1458   * @param buffer Pointer to the data to creat a checksum for.
 1459   * @param numBytes Number of bytes that (buffer) points to.
 1460   * @returns A 32-bit number based on the contents of the buffer.
 1461   */
 1462 static inline uint32 CalculateChecksum(const void * buffer, uint32 numBytes) {return CalculateHashCode(buffer, numBytes);}
 1463 
 1464 /** Convenience method:  Given a uint64, returns a corresponding 32-bit checksum value */
 1465 static inline uint32 CalculateChecksumForUint64(uint64 v) {uint64 le = B_HOST_TO_LENDIAN_INT64(v);   return CalculateChecksum(&le, sizeof(le));}
 1466 
 1467 /** Convenience method:  Given a float, returns a corresponding 32-bit checksum value */
 1468 static inline uint32 CalculateChecksumForFloat(float v)   {uint32 le = (v==0.0f) ? 0 : B_HOST_TO_LENDIAN_IFLOAT(v); return CalculateChecksum(&le, sizeof(le));}  // yes, the special case for 0.0f IS necessary, because the sign-bit might be set.  :(
 1469 
 1470 /** Convenience method:  Given a double, returns a corresponding 32-bit checksum value */
 1471 static inline uint32 CalculateChecksumForDouble(double v) {uint64 le = (v==0.0) ? 0 : B_HOST_TO_LENDIAN_IDOUBLE(v); return CalculateChecksum(&le, sizeof(le));}  // yes, the special case for 0.0 IS necessary, because the sign-bit might be set.  :(
 1472 
 1473 /** Convenience method:  Returns the Euclidean modulo of the given value for the given divisor.
 1474   * @param value the value to calculate the Euclidean-modulo of
 1475   * @param divisor the divisor to use in the calculation.  Must not be zero.
 1476   * @note For non-negative values of (value), this function behaves the same as (value%divisor).
 1477   *       For negative values of (value), this function behaves differently
 1478   *       in that e.g. EuclideanModulo(-1,d) will return (d-1) rather than -1.  This is
 1479   *       arguably more useful for cyclic-sequence applications, as there will not be
 1480   *       any anomalies in the resulting values as (value) transitions between positive and negative.
 1481   */
 1482 static inline uint32 EuclideanModulo(int32 value, uint32 divisor)
 1483 {
 1484    // Derived from the code posted at https://stackoverflow.com/a/51959866/131930
 1485    return (value < 0) ? ((divisor-1)-((-1-value)%divisor)) : (value%divisor);
 1486 }
 1487  
 1488 /** This hashing functor type handles the trivial cases, where the KeyType is
 1489  *  Plain Old Data that we can just feed directly into the CalculateHashCode() function.
 1490  *  For more complicated key types, you should define a method in your KeyType class
 1491  *  that looks like this:
 1492  *      uint32 HashCode() const {return the_calculated_hash_code_for_this_object();}
 1493  *  And that will be enough for the template magic to kick in and use MethodHashFunctor
 1494  *  by default instead.  (See util/String.h for an example of this)
 1495  */
 1496 template <class KeyType> class PODHashFunctor
 1497 {
 1498 public:
 1499    uint32 operator()(const KeyType & x) const 
 1500    {
 1501 #ifndef MUSCLE_AVOID_CPLUSPLUS11
 1502       static_assert(!std::is_class<KeyType>::value, "PODHashFunctor cannot be used on class or struct objects, because the object's compiler-inserted padding bytes would be unitialized and therefore they would cause inconsistent hash-code generation.  Try adding a 'uint32 HashCode() const' method to the class/struct instead.");
 1503       static_assert(!std::is_union<KeyType>::value, "PODHashFunctor cannot be used on union objects.");
 1504 #endif
 1505       return CalculateHashCode(x);
 1506    }
 1507    bool AreKeysEqual(const KeyType & k1, const KeyType & k2) const {return (k1==k2);}
 1508 };
 1509 
 1510 /** This hashing functor type calls HashCode() on the supplied object to retrieve the hash code. */
 1511 template <class KeyType> class MethodHashFunctor
 1512 {
 1513 public:
 1514    uint32 operator()(const KeyType & x) const {return x.HashCode();}
 1515    bool AreKeysEqual(const KeyType & k1, const KeyType & k2) const {return (k1==k2);}
 1516 };
 1517 
 1518 /** This hashing functor type calls HashCode() on the supplied object to retrieve the hash code.  Used for pointers to key values. */
 1519 template <typename KeyType> class MethodHashFunctor<KeyType *>
 1520 {
 1521 public:
 1522    uint32 operator()(const KeyType * x) const {return x->HashCode();}
 1523 
 1524    /** Note that when pointers are used as hash keys, we determine equality by comparing the objects
 1525      * the pointers point to, NOT by just comparing the pointers themselves!
 1526      */
 1527    bool AreKeysEqual(const KeyType * k1, const KeyType * k2) const {return ((*k1)==(*k2));}
 1528 };
 1529 
 1530 /** This macro can be used whenever you want to explicitly specify the default AutoChooseHashFunctorHelper functor for your type.  It's easier than remembering the tortured C++ syntax */
 1531 #define DEFAULT_HASH_FUNCTOR(type) AutoChooseHashFunctorHelper<type>::Type
 1532 
 1533 #ifndef DOXYGEN_SHOULD_IGNORE_THIS
 1534 namespace ugly_hashcode_method_sfinae_implementation
 1535 {
 1536    // This code was adapted from the example code at http://www.martinecker.com/wiki/index.php?title=Detecting_the_Existence_of_Member_Functions_at_Compile-Time
 1537    // It is used by the AutoChooseHashFunctorHelper (below) to automatically choose the appropriate HashFunctor
 1538    // type based on whether or not class given in the template argument has a "uint32 HashCode() const" method defined.
 1539 
 1540    typedef char yes;
 1541    typedef char (&no)[2];
 1542    template <typename T, uint32 (T::*f)() const> struct test_hashcode_wrapper {};
 1543 
 1544    // via SFINAE only one of these overloads will be considered
 1545    template <typename T> yes hashcode_tester(test_hashcode_wrapper<T, &T::HashCode>*);
 1546    template <typename T> no  hashcode_tester(...);
 1547 
 1548    template <typename T> struct test_hashcode_impl {static const bool value = sizeof(hashcode_tester<T>(0)) == sizeof(yes);};
 1549 
 1550    template <class T> struct has_hashcode_method : test_hashcode_impl<T> {};
 1551    template <bool Condition, typename TrueResult, typename FalseResult> struct if_;
 1552    template <typename TrueResult, typename FalseResult> struct if_<true,  TrueResult, FalseResult> {typedef TrueResult  result;};
 1553    template <typename TrueResult, typename FalseResult> struct if_<false, TrueResult, FalseResult> {typedef FalseResult result;};
 1554 }
 1555 #endif
 1556 
 1557 template<typename ItemType> class AutoChooseHashFunctorHelper
 1558 {
 1559 public:
 1560    typedef typename ugly_hashcode_method_sfinae_implementation::if_<ugly_hashcode_method_sfinae_implementation::test_hashcode_impl<ItemType>::value, MethodHashFunctor<ItemType>, PODHashFunctor<ItemType> >::result Type;
 1561 };
 1562 template <typename ItemType> class AutoChooseHashFunctorHelper<ItemType *>
 1563 {
 1564 public:
 1565    typedef typename ugly_hashcode_method_sfinae_implementation::if_<ugly_hashcode_method_sfinae_implementation::test_hashcode_impl<ItemType>::value, MethodHashFunctor<ItemType *>, PODHashFunctor<ItemType *> >::result Type;
 1566 };
 1567 
 1568 /** This HashFunctor lets us use (const char *)'s as keys in a Hashtable.  They will be
 1569   * hashed based on contents of the string they point to.
 1570   */
 1571 template <> class PODHashFunctor<const char *>
 1572 {
 1573 public:
 1574    /** Returns a hash code for the given C string.
 1575      * @param str The C string to compute a hash code for.
 1576      */
 1577    uint32 operator () (const char * str) const {return CalculateHashCode(str, (uint32)strlen(str));}
 1578    bool AreKeysEqual(const char * k1, const char * k2) const {return (strcmp(k1,k2)==0);}
 1579 };
 1580 
 1581 template <> class AutoChooseHashFunctorHelper<const void *> {typedef PODHashFunctor<const void *> Type;};
 1582 template <> class AutoChooseHashFunctorHelper<char *>       {typedef PODHashFunctor<char *>       Type;};
 1583 template <> class AutoChooseHashFunctorHelper<void *>       {typedef PODHashFunctor<void *>       Type;};
 1584 
 1585 // Hacked-in support for g++ 3.x compilers, that don't handle the AutoChooseHashFunctionHelper SFINAE magic properly
 1586 #if defined(__GNUC__) && (__GNUC__ <= 3)
 1587 # define AUTOCHOOSE_LEGACY_PRIMITIVE_KEY_TYPE_HACK(x) template <> class muscle::AutoChooseHashFunctorHelper<x> {public: typedef muscle::PODHashFunctor<x> Type;}
 1588 # define AUTOCHOOSE_LEGACY_PRIMITIVE_KEY_TYPE_HACK_WITH_NAMESPACE(ns,x) }; namespace muscle {template <> class AutoChooseHashFunctorHelper<ns::x> {public: typedef PODHashFunctor<ns::x> Type;};}; namespace ns {
 1589  AUTOCHOOSE_LEGACY_PRIMITIVE_KEY_TYPE_HACK(int);
 1590  AUTOCHOOSE_LEGACY_PRIMITIVE_KEY_TYPE_HACK(int8);
 1591  AUTOCHOOSE_LEGACY_PRIMITIVE_KEY_TYPE_HACK(uint8);
 1592  AUTOCHOOSE_LEGACY_PRIMITIVE_KEY_TYPE_HACK(int16);
 1593  AUTOCHOOSE_LEGACY_PRIMITIVE_KEY_TYPE_HACK(uint16);
 1594  AUTOCHOOSE_LEGACY_PRIMITIVE_KEY_TYPE_HACK(int32);
 1595  AUTOCHOOSE_LEGACY_PRIMITIVE_KEY_TYPE_HACK(uint32);
 1596  AUTOCHOOSE_LEGACY_PRIMITIVE_KEY_TYPE_HACK(int64);
 1597  AUTOCHOOSE_LEGACY_PRIMITIVE_KEY_TYPE_HACK(uint64);
 1598  AUTOCHOOSE_LEGACY_PRIMITIVE_KEY_TYPE_HACK(const char *);
 1599  AUTOCHOOSE_LEGACY_PRIMITIVE_KEY_TYPE_HACK(float);
 1600  AUTOCHOOSE_LEGACY_PRIMITIVE_KEY_TYPE_HACK(DataNode *);  // FogBugz #9816 tweakage --jaf
 1601 #else
 1602 # define AUTOCHOOSE_LEGACY_PRIMITIVE_KEY_TYPE_HACK(x)
 1603 # define AUTOCHOOSE_LEGACY_PRIMITIVE_KEY_TYPE_HACK_WITH_NAMESPACE(ns,x)
 1604 #endif
 1605 
 1606 #endif
 1607 
 1608 // VC++6 and earlier can't handle partial template specialization, so
 1609 // they need some extra help at various places.  Lame....
 1610 #if defined(_MSC_VER)
 1611 # if (_MSC_VER < 1300)
 1612 #  define MUSCLE_USING_OLD_MICROSOFT_COMPILER 1  // VC++6 and earlier
 1613 # else
 1614 #  define MUSCLE_USING_NEW_MICROSOFT_COMPILER 1  // VC.net2004 and later
 1615 # endif
 1616 #endif
 1617 
 1618 /** Given an ASCII decimal representation of a non-negative number, returns that number as a uint64. */
 1619 uint64 Atoull(const char * str);
 1620 
 1621 /** Similar to Atoll(), but handles negative numbers as well */
 1622 int64 Atoll(const char * str);
 1623 
 1624 /** Given an ASCII hexadecimal representation of a non-negative number (with or without the optional "0x" prefix), returns that number as a uint64. */
 1625 uint64 Atoxll(const char * str);
 1626 
 1627 #ifdef __cplusplus
 1628 } // end namespace muscle
 1629 #endif
 1630 
 1631 #endif /* _MUSCLE_SUPPORT_H */