text:
=======================
Duktape feature options
=======================

Overview
========

The effective set of Duktape features is resolved in three steps:

* User defines ``DUK_OPT_xxx`` feature options.  These are essentially
  requests to enable/disable some feature.

* Duktape feature resolution in ``duk_features.h.in`` takes into account
  the requested features, the platform, the compiler, the operating system
  etc, and defines ``DUK_USE_xxx`` internal use flags.  Other parts of
  Duktape only listen to these "use flags", so that feature resolution is
  strictly contained.

* User may optionally have a ``duk_custom.h`` header which can further
  tweak the effective ``DUK_USE_xxx`` defines.  This is a last resort and
  is somewhat fragile.  See ``DUK_OPT_HAVE_CUSTOM_H`` for more discussion.

This document describes all the supported Duktape feature options and should
be kept up-to-date with new features.  The feature option list in the guide
is a subset of the most commonly needed features.

See also:

- ``low-memory.rst``: suggested options for low memory environments

- ``timing-sensitive.rst``: suggested options for timing sensitive environments

- ``src/duk_features.h.in``: resolution of feature options to use flags

Feature option naming
=====================

Feature options that enable a certain (default) feature are named::

  DUK_OPT_MY_FEATURE

Feature options that disable a (default) feature are named::

  DUK_OPT_NO_MY_FEATURE

Both flags are reserved at the same time.  One of the options will match
the default behavior, so it won't actually be implemented.

Some feature options have a value associated with them.  This is the case
for e.g. ``DUK_OPT_PANIC_HANDLER`` or ``DUK_OPT_FORCE_ALIGN``.  These are
handled case by case.

Avoid using words like "disable" in the feature naming.  This will lead to
odd names if the default behavior changes and a "no disable" flag is needed.

Platform and portability options
================================

DUK_OPT_DLL_BUILD
-----------------

Add this define to both Duktape and application build when Duktape is compiled
as a DLL.  This is especially critical on Windows: the option makes Duktape use
``__declspec(dllexport)`` and ``__declspec(dllimport)`` for public symbols.
While this is not currently needed for Unix platforms, it should always be used
if you build as a DLL.

DUK_OPT_FORCE_ALIGN
-------------------

Use ``-DDUK_OPT_FORCE_ALIGN=4`` or ``-DDUK_OPT_FORCE_ALIGN=8`` to force a
specific struct/value alignment instead of relying on Duktape's automatic
detection.  This shouldn't normally be needed.

DUK_OPT_FORCE_BYTEORDER
-----------------------

Use this to skip byte order detection and force a specific byte order:
``1`` for little endian, ``2`` for ARM "mixed" endian (integers little
endian, IEEE doubles mixed endian), ``3`` for big endian.  Byte order
detection relies on unstandardized platform specific header files, so
this may be required for custom platforms if compilation fails in
endianness detection.

DUK_OPT_NO_FILE_IO
------------------

Disable use of ANSI C file I/O which might be a portability issue on some
platforms.  Causes ``duk_eval_file()`` to throw an error, makes built-in
``print()`` and ``alert()`` no-ops, and suppresses writing of a panic
message to ``stderr`` on panic.  This option does not suppress debug
printing so don't enable debug printing if you wish to avoid I/O.

DUK_OPT_HAVE_CUSTOM_H
---------------------

Enable user-provided ``duk_custom.h`` customization header (see below for
details).  Not recommended unless really necessary.

DUK_OPT_PANIC_HANDLER(code,msg)
-------------------------------

Provide a custom panic handler, see detailed description below.

DUK_OPT_DECLARE
---------------

Provide declarations or additional #include directives to be used when
compiling Duktape.  You may need this if you set ``DUK_OPT_PANIC_HANDLER``
to call your own panic handler function (see example below).  You can also
use this option to cause additional files to be included when compiling
Duktape.

DUK_OPT_SEGFAULT_ON_PANIC
-------------------------

Cause the default panic handler to cause a segfault instead of using
``abort()`` or ``exit()``.  This is useful when debugging with valgrind,
as a segfault provides a nice C traceback in valgrind.

DUK_OPT_USER_INITJS
-------------------

Provide a string to evaluate when a thread with new built-ins (a new global
environment) is created.  This allows you to make minor modifications to the
global environment before any code is executed in it.  The value must be a
string, e.g.::

    -DDUK_OPT_USER_INITJS='"this.foo = 123"'

Errors in the initialization code result in a fatal error.

(This option will most likely be deprecated in favor of an actual callback
which provides much more flexibility for extending the global environment,
implementing sandboxing, etc.)

DUK_OPT_SETJMP
--------------

Force ``setjmp/longjmp`` for long control transfers.

The default long control transfer provider is ``setjmp/longjmp`` because it
is the most portable option.  When a better provider is known for a platform,
Duktape may default to that (e.g. ``_setjmp/_longjmp`` is the default for
OSX/iPhone, see GH-55).  With this feature option you can force Duktape to
explicitly use ``setjmp/longjmp`` even in these cases.

The downside of ``setjmp/longjmp`` is that signal mask saving behavior is not
specified and varies between platforms.  Signal mask saving may have a
significant performance impact so you may want to force a specific provider
if performance matters for your application.

DUK_OPT_UNDERSCORE_SETJMP
-------------------------

Force ``_setjmp/_longjmp`` for long control transfers.  This ensures signal
mask is not saved which can be a lot faster if ``setjmp/longjmp`` saves the
signal mask (this varies between platforms).  See comments in
``DUK_OPT_SETJMP``.

DUK_OPT_SIGSETJMP
-----------------

Force ``sigsetjmp/siglongjmp`` with ``savesigs == 0`` for long control
transfers (i.e. signal mask not saved/restored).  See comments in
``DUK_OPT_SETJMP``.

Memory management options
=========================

DUK_OPT_EXTERNAL_STRINGS
------------------------

Enable support for external strings.  An external string requires a Duktape
heap allocation to store a minimal string header, with the actual string
data being held behind a pointer (similarly to how dynamic buffers work).

This is needed to use ``DUK_OPT_EXTSTR_INTERN_CHECK`` and/or
``DUK_OPT_EXTSTR_FREE``.

DUK_OPT_NO_PACKED_TVAL
----------------------

Don't use the packed 8-byte internal value representation even if otherwise
possible.  The packed representation has more platform/compiler portability
issues than the unpacked one.

DUK_OPT_DEEP_C_STACK
--------------------

By default Duktape imposes a sanity limit on the depth of the C stack because
it is often limited in embedded environments.  This option forces Duktape to
use a deep C stack which relaxes e.g. recursion limits.  Automatic feature
detection enables deep C stacks on some platforms known to have them (e.g.
Linux, BSD, Windows).

DUK_OPT_NO_REFERENCE_COUNTING
-----------------------------

Disable reference counting and use only mark-and-sweep for garbage collection.
Although this reduces memory footprint of heap objects, the downside is much
more fluctuation in memory usage.

DUK_OPT_NO_MARK_AND_SWEEP
-------------------------

Disable mark-and-sweep and use only reference counting for garbage collection.
This reduces code footprint and eliminates garbage collection pauses, but
objects participating in unreachable reference cycles won't be collected until
the Duktape heap is destroyed.  In particular, function instances won't be
collected because they're always in a reference cycle with their default
prototype object.  Unreachable objects are collected if you break reference
cycles manually (and are always freed when a heap is destroyed).

DUK_OPT_NO_VOLUNTARY_GC
-----------------------

Disable voluntary periodic mark-and-sweep collection.  A mark-and-sweep
collection is still triggered in an out-of-memory condition.  This option
should usually be combined with reference counting, which collects all
non-cyclical garbage.  Application code should also request an explicit
garbage collection from time to time when appropriate.  When this option
is used, Duktape will have no garbage collection pauses in ordinary use,
which is useful for timing sensitive applications like games.

DUK_OPT_NO_MS_STRINGTABLE_RESIZE
--------------------------------

Disable forced string intern table resize during mark-and-sweep garbage
collection.  This may be useful when reference counting is disabled, as
mark-and-sweep collections will be more frequent and thus more expensive.

DUK_OPT_GC_TORTURE
------------------

Development time option: force full mark-and-sweep on every allocation to
stress test memory management.

Low memory feature options
==========================

These options are low memory features for systems with 96-256 kB of RAM.
Unless you have very little RAM, these options are probably not relevant
to you.  They involve some compromises in e.g. performance or compliance
to reduce memory usage.

**The low memory feature options are experimental in Duktape 1.1, i.e. they
may change in an incompatible manner in Duktape 1.2.**

DUK_OPT_REFCOUNT16
------------------

Use a 16-bit reference count field (for low memory environments).

DUK_OPT_STRHASH16
-----------------

Use a 16-bit string hash field (for low memory environments).

DUK_OPT_STRLEN16
----------------

Use a 16-bit string length field (for low memory environments).

DUK_OPT_BUFLEN16
----------------

Use a 16-bit buffer length field (for low memory environments).

DUK_OPT_OBJSIZE16
-----------------

Use a 16-bit object entry and array part sizes (for low memory environments).
Also automatically drops support for an object hash part to further reduce
memory usage; there are rarely large objects in low memory environments simply
because there's no memory to store a lot of properties.

DUK_OPT_HEAPPTR16, DUK_OPT_HEAPPTR_ENC16, DUK_OPT_HEAPPTR_DEC16
---------------------------------------------------------------

Enable "compression" of Duktape heap pointers into an unsigned 16-bit value
and provide the macros for encoding and decoding a pointer:

- Pointers compressed are those allocated from Duktape heap, using the
  user provided allocation functions.  Also NULL pointer must encode and
  decode correctly.

- Currently it is required that NULL encodes to integer 0, and integer
  0 decodes to NULL.  No other pointer can be encoded to 0.

- DUK_OPT_HEAPPTR_ENC16(udata,p) is a macro with a userdata and ``void *``
  argument, and a ``duk_uint16_t`` return value.

- DUK_OPT_HEAPPTR_DEC16(udata,x) is a macro with a userdata and
  ``duk_uint16_t`` argument, and a ``void *`` return value.

- The userdata argument is the heap userdata value given at heap creation.

- See ``ajduk`` example in Duktape ``Makefile`` for a concrete example.

This option reduces memory usage by several kilobytes, but has several
downsides:

- It can only be applied when Duktape heap is limited in size.  For instance,
  with 4-byte aligned allocations a 256kB heap (minus one value for NULL)
  can be supported.

- Pointer encoding and decoding may be relatively complicated as they need to
  correctly handle NULL pointers and non-continuous memory maps used by some
  targets.  The macro may need to call out to a helper function in practice,
  which is much slower than an inline implementation.

Current limitations:

- Duktape internal debug code enabled with e.g. ``DUK_OPT_DEBUG`` and
  ``DUK_OPT_DPRINT`` doesn't have enough plumbing to be able to decode
  pointers.  Debug printing cannot currently be enabled when pointer
  compression is active.

DUK_OPT_DATAPTR16, DUK_OPT_DATAPTR_ENC16, DUK_OPT_DATAPTR_DEC16
---------------------------------------------------------------

Enable "compression" of arbitrary data pointers into an unsigned 16-bit value
and provide the macros for encoding and decoding a pointer:

- Pointers compressed are any void pointers in C code, not just the Duktape
  heap.  Also NULL pointer must encode and decode correctly.

- Currently it is required that NULL encodes to integer 0, and integer
  0 decodes to NULL.  No other pointer can be encoded to 0.

- DUK_OPT_DATAPTR_ENC16(udata,p) is a macro with a userdata and ``void *``
  argument, and a ``duk_uint16_t`` return value.

- DUK_OPT_DATAPTR_DEC16(udata,x) is a macro with a userdata and
  ``duk_uint16_t`` argument, and a ``void *`` return value.

- The userdata argument is the heap userdata value given at heap creation.

.. note:: This feature option is currently unimplemented, i.e. Duktape won't compress
          any data pointers at the moment.

DUK_OPT_FUNCPTR16, DUK_OPT_FUNCPTR_ENC16, DUK_OPT_FUNCPTR_DEC16
---------------------------------------------------------------

Enable "compression" of arbitrary C function pointers into an unsigned 16-bit
value and provide the macros for encoding and decoding a pointer:

- Pointers compressed are any C function pointers.  Also NULL pointer must
  encode and decode correctly.

- Currently it is required that NULL encodes to integer 0, and integer
  0 decodes to NULL.  No other pointer can be encoded to 0.

- DUK_OPT_FUNCPTR_ENC16(udata,p) is a macro with a userdata and ``void *``
  argument, and a ``duk_uint16_t`` return value.

- DUK_OPT_FUNCPTR_DEC16(udata,x) is a macro with a userdata and
  ``duk_uint16_t`` argument, and a ``void *`` return value.

- The userdata argument is the heap userdata value given at heap creation.

.. note:: This feature option is currently unimplemented, i.e. Duktape won't compress
          any function pointers at the moment.  It might not be necessary to support a
          NULL function pointer.

DUK_OPT_EXTSTR_INTERN_CHECK(udata,ptr,len)
------------------------------------------

Provide a hook for checking if data for a certain string can be used from
external memory (outside of Duktape heap, e.g. memory mapped flash).
The hook is called during string interning with the following semantics:

* The string data with no NUL termination resides at ``ptr`` and has ``len``
  bytes.  The ``udata`` argument is the heap userdata which may be ignored
  if not needed.

* If the hook returns NULL, Duktape interns the string normally, i.e.
  string data is allocated from Duktape heap.

* Otherwise the hook return value must point to a memory area which contains
  ``len`` bytes from ``ptr`` followed by a NUL byte which is **not present**
  in the input data.  Data behind the returned pointer may not change after
  the hook returns.

Notes:

* Also enable ``DUK_OPT_EXTERNAL_STRINGS`` to use this feature.

* The hook may be called several times for the same input string.  This
  happens when a string is interned, garbage collected, and then interned
  again.

* The ``DUK_OPT_EXTSTR_FREE()`` hook allows application code to detect when
  an external string is about to be freed.

* In most cases the hook should reject strings whose ``len`` is less than 4
  because there is no RAM advantage in moving so short strings into external
  memory.  The ordinary ``duk_hstring`` header followed by the data (and a
  NUL byte) has the same size as ``duk_hstring_external`` header which hosts
  a pointer instead of string data.

See ``low-memory.rst`` for more discussion how to use this feature option
in practice.

DUK_OPT_EXTSTR_FREE(udata,ptr)
------------------------------

Optional counterpart to ``DUK_OPT_EXTSTR_INTERN_CHECK``, with the following
semantics:

* Also enable ``DUK_OPT_EXTERNAL_STRINGS`` to use this feature.

* The macro is invoked when an external string is about to be freed.

* The argument ``ptr`` is a ``void *`` and points to the external string data.
  Concretely, it is the (non-NULL) value returned by
  ``DUK_OPT_EXTSTR_INTERN_CHECK``.  The ``udata`` argument is the heap
  userdata which may be ignored if not needed.

.. note:: Right now there is no API to push external strings; external strings
          come into being as a resul of DUK_OPT_EXTSTR_INTERN_CHECK() only.
          If/when this is changed, this hook will get called for every string,
          even if pushed by the user using an API call; this may need to be
          rethought at that time.

DUK_OPT_STRTAB_CHAIN, DUK_OPT_STRTAB_CHAIN_SIZE
-----------------------------------------------

Replace the default (open addressing, probing) string table structure with one
based on separate chaining.  There is a fixed-size top level hash table (whose
size is defined using ``DUK_OPT_STRTAB_CHAIN_SIZE``), with each entry in the
hash table being: (a) NULL, (b) a ``duk_hstring`` pointer, or (c) a pointer
to an array of ``duk_hstring`` pointers.  The pointer arrays are gappy (the
gaps are reused on new inserts) and are never shrunk at the moment.

This option is intended for low memory environments to make Duktape's memory
behavior match a typical pool-based allocator better:

* The top level fixed structure never changes size, so there is no hash table
  resize, and thus no need for resize temporaries.  The default string table
  algorithm needs resizing from time to time and doesn't resize in place, so
  you effectively need twice the string table size temporarily during a resize.

* The pointer arrays vary in size, but their size (typically 8 to 64 bytes,
  depending on the load factor) matches that of many other allocations which
  works well with a pooled allocator.

Ecmascript feature options
==========================

DUK_OPT_NO_AUGMENT_ERRORS
-------------------------

Don't augment Ecmascript error objects with custom fields like ``fileName``,
``lineNumber``, and traceback data.  Also disables ``Duktape.errCreate`` and
``Duktape.errThrow`` error handler callbacks.  Implies ``DUK_OPT_NO_TRACEBACKS``.

DUK_OPT_NO_TRACEBACKS
---------------------

Don't record traceback data into Ecmascript error objects (but still record
``fileName`` and ``lineNumber``).  Reduces footprint and makes error handling
a bit faster, at the cost of less informative Ecmascript errors.

DUK_OPT_NO_VERBOSE_ERRORS
-------------------------

Don't provide error message strings or filename/line information for errors
generated by Duktape.  Reduces footprint, at the cost of much less informative
Ecmascript errors.

DUK_OPT_TRACEBACK_DEPTH
-----------------------

Override default traceback collection depth.  The default is currently 10.

DUK_OPT_NO_PC2LINE
------------------

Don't record a "pc2line" map into function instances.  Without this map,
exceptions won't have meaningful line numbers (virtual machine program
counter values cannot be translated to line numbers) but function instances
will have a smaller footprint.

DUK_OPT_NO_STRICT_DECL
----------------------

**Experimental.**

Disable support for ``"use strict"`` declaration so that Ecmascript code is
always executed in non-strict mode.  Duktape/C functions remain strict.

.. note:: This mechanism is EXPERIMENTAL and the details may change
          between releases.

DUK_OPT_NO_REGEXP_SUPPORT
-------------------------

Disable support for regular expressions.  Regexp literals are treated as a
``SyntaxError``, RegExp constructor and prototype functions throw an error,
``String.prototype.replace()`` throws an error if given a regexp search value,
``String.prototype.split()`` throws an error if given a regexp separator
value, ``String.prototype.search()`` and ``String.prototype.match()`` throw an
error unconditionally.

DUK_OPT_STRICT_UTF8_SOURCE
--------------------------

Enable strict UTF-8 parsing of source code.  When enabled, non-shortest
encodings (normally invalid UTF-8) and surrogate pair codepoints are accepted
as valid source code characters.  This option breaks compatibility with
some test262 tests.

DUK_OPT_NO_OCTAL_SUPPORT
------------------------

Disable optional octal number support (Ecmascript E5/E5.1
`Annex B <http://www.ecma-international.org/ecma-262/5.1/#sec-B>`_).

DUK_OPT_NO_SOURCE_NONBMP
------------------------

Disable accurate Unicode support for non-BMP characters in source code.
Non-BMP characters are then always accepted as identifier characters.

DUK_OPT_NO_BROWSER_LIKE
-----------------------

Disable browser-like functions.  Makes ``print()`` and ``alert()`` throw an
error.  This option is confusing when used with the Duktape command line tool,
as the command like tool will immediately panic.

DUK_OPT_NO_SECTION_B
--------------------

Disable optional features in Ecmascript specification
`Annex B <http://www.ecma-international.org/ecma-262/5.1/#sec-B>`_.
Causes ``escape()``, ``unescape()``, and ``String.prototype.substr()`` to
throw an error.

DUK_OPT_NO_NONSTD_ACCESSOR_KEY_ARGUMENT
---------------------------------------

Don't give setter/getter calls the property name being accessed as
an additional, non-standard property.  See
`Property virtualization <http://duktape.org/guide.html#propertyvirtualization>`_.

DUK_OPT_NO_NONSTD_FUNC_STMT
---------------------------

Disable support for function declarations outside program or function top
level (also known as "function statements").  Such declarations are
non-standard and the strictly compliant behavior is to treat them as a
SyntaxError.  Default behavior is to treat them like ordinary function
declarations ("hoist" them to function top) with V8-like semantics.

DUK_OPT_NONSTD_FUNC_CALLER_PROPERTY
-----------------------------------

Add a non-standard ``caller`` property to non-strict function instances
for better compatibility with existing code.  The semantics of this
property are not standardized and may vary between engines; Duktape tries
to behave close to V8 and Spidermonkey.  See
`Mozilla <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/caller>`_
description of the property.  This feature disables tail call support.

This feature conflicts with several other features, so you should use it
only if it's absolutely necessary.

DUK_OPT_NONSTD_FUNC_SOURCE_PROPERTY
-----------------------------------

Add a non-standard ``source`` property to function instances.  This allows
function ``toString()`` to print out the actual function source.  The
property is disabled by default because it increases memory footprint.

.. note:: Unimplemented as of Duktape 0.12.0.

DUK_OPT_NO_NONSTD_ARRAY_SPLICE_DELCOUNT
---------------------------------------

For better compatibility with existing code, ``Array.prototype.splice()``
has non-standard behavior by default when the second argument (deleteCount)
is not given: the splice operation is extended to the end of the array,
see
`test-bi-array-proto-splice-no-delcount.js <https://github.com/svaarala/duktape/blob/master/ecmascript-testcases/test-bi-array-proto-splice-no-delcount.js>`_.
If this option is given, ``splice()`` will behave in a strictly
conforming fashion, treating a missing deleteCount the same as an undefined
(or 0) value.

DUK_OPT_NO_NONSTD_ARRAY_CONCAT_TRAILER
--------------------------------------

For better compatibility with existing code, ``Array.prototype.concat()``
has non-standard behavior by default for trailing non-existent elements of
the concat result, see
`test-bi-array-proto-concat-nonstd-trailing.js <https://github.com/svaarala/duktape/blob/master/ecmascript-testcases/test-bi-array-proto-concat-nonstd-trailing.js>`_.
If this option is given, ``concat()`` will behave in a strictly conforming
fashion, ignoring non-existent trailing elements in the result ``length``.

DUK_OPT_NO_NONSTD_ARRAY_MAP_TRAILER
-----------------------------------

For better compatibility with existing code, ``Array.prototype.map()``
has non-standard behavior by default for trailing non-existent elements
of the map result, see
`test-bi-array-proto-map-nonstd-trailing.js <https://github.com/svaarala/duktape/blob/master/ecmascript-testcases/test-bi-array-proto-map-nonstd-trailing.js>`_.
If this option is given, ``map()`` will behave in a strictly conforming
fashion, ignoring non-existent trailing elements in the result ``length``.

DUK_OPT_NO_NONSTD_JSON_ESC_U2028_U2029
--------------------------------------

By default Duktape JSON.stringify() will escape U+2028 and U+2029 which
is non-compliant behavior.  This is the default to make JSON.stringify()
output valid when embedded in a web page or parsed with ``eval()``.  This
feature option enables the compliant behavior, i.e. no escaping for U+2028
and U+2029.

DUK_OPT_NO_COMMONJS_MODULES
---------------------------

Disable support for CommonJS modules.  Causes ``require()`` to throw an
error.

DUK_OPT_NO_ES6_OBJECT_PROTO_PROPERTY
------------------------------------

Disable the non-standard (ES6 draft) ``Object.prototype.__proto__``
property which is enabled by default.

DUK_OPT_NO_ES6_OBJECT_SETPROTOTYPEOF
------------------------------------

Disable the non-standard (ES6 draft) ``Object.setPrototypeOf`` method
which is enabled by default.

DUK_OPT_NO_ES6_PROXY
--------------------

Disable the non-standard (ES6 draft) ``Proxy`` object which is enabled
by default.

DUK_OPT_NO_JX
-------------

Disable support for the JX format.  Reduces code footprint.  An attempt
to encode or decode the format causes an error.

DUK_OPT_NO_JC
-------------

Disable support for the JC format.  Reduces code footprint.  An attempt
to encode or decode the format causes an error.

DUK_OPT_LIGHTFUNC_BUILTINS
--------------------------

**Experimental.**

Force built-in functions to be lightweight functions.  This reduces
memory footprint by around 14 kB at the cost of some non-compliant
behavior.

Execution and debugger options
==============================

DUK_OPT_INTERRUPT_COUNTER
-------------------------

Enable the internal bytecode executor periodic interrupt counter.
The mechanism is used to implement e.g. execution step limit, custom
profiling, and debugger interaction.  Enabling the interrupt counter
has a small impact on execution performance.

DUK_OPT_EXEC_TIMEOUT_CHECK
--------------------------

**Experimental.**

Provide a hook to check for bytecode execution timeout.  The macro gets
a ``void *`` userdata argument (the userdata given to ``duk_heap_create()``)
and must evaluate to a ``duk_bool_t``.  Duktape calls it as::

    if (DUK_OPT_EXEC_TIMEOUT_CHECK(udata)) { ... }

The macro is called occasionally by the Duktape bytecode executor (i.e. when
executing Ecmascript code), typically from a few times per second to a hundred
times per second, but the interval varies a great deal depending on what kind
of code is being executed.

To indicate an execution timeout, the macro must return a non-zero value.
When that happens, Duktape starts to bubble a ``RangeError`` outwards
until control has been returned to the original protected call made by
the application.  Until that happens, the exec timeout macro must always
return non-zero to indicate an execution timeout is still in progress.

This mechanism and its limitations is described in more detail in
``doc/sandboxing.rst``.

.. note:: This mechanism is EXPERIMENTAL and the details may change
          between releases.

Debugging options
=================

DUK_OPT_SELF_TESTS
------------------

Perform run-time self tests when a Duktape heap is created.  Catches
platform/compiler problems which cannot be reliably detected during
compile time.  Not enabled by default because of the extra footprint.

DUK_OPT_ASSERTIONS
------------------

Enable internal assert checks.  These slow down execution considerably
so only use when debugging.

DUK_OPT_DEBUG
-------------

Enable debug code in Duktape internals.  Without this option other
debugging options (such as ``DUK_OPT_DPRINT``) have no effect.

DUK_OPT_DPRINT
--------------

Enable debug printouts.

DUK_OPT_DDPRINT
---------------

Enable more debug printouts.

DUK_OPT_DDDPRINT
----------------

Enable even more debug printouts.  Not recommended unless you have
grep handy.

DUK_OPT_DPRINT_COLORS
---------------------

Enable coloring of debug prints with
`ANSI escape codes <http://en.wikipedia.org/wiki/ANSI_escape_code>`_.
The behavior is not sensitive to terminal settings.

DUK_OPT_DPRINT_RDTSC
--------------------

Print RDTSC cycle count in debug prints if available.

DUK_OPT_DEBUG_BUFSIZE
---------------------

Debug code uses a static buffer as a formatting temporary to avoid side
effects in debug prints.  The static buffer is large by default, which may
be an issue in constrained environments.  You can set the buffer size
manually with this option.  Example::

    -DDUK_OPT_DEBUG_BUFSIZE=2048

DUK_OPT_NO_ZERO_BUFFER_DATA
---------------------------

By default Duktape zeroes data allocated for buffer values.  Define
this to disable the zeroing (perhaps for performance reasons).

Using DUK_OPT_HAVE_CUSTOM_H and duk_custom.h
============================================

Normally you define ``DUK_OPT_xxx`` feature options and the internal
``duk_features.h`` header resolves these with platform/compiler constraints
to determine effective compilation options for Duktape internals.  The
effective options are provided as ``DUK_USE_xxx`` defines which you normally
never see.

If you define ``DUK_OPT_HAVE_CUSTOM_H``, Duktape will include
``duk_custom.h`` after determining the appropriate ``DUK_USE_xxx`` defines
but before compiling any code.  The ``duk_custom.h`` header, which you
provide, can then tweak the active ``DUK_USE_xxx`` defines freely.  See
``duk_features.h`` for the available defines.

This approach is useful when the ``DUK_OPT_xxx`` feature options don't
provide enough flexibility to tweak the build.  The downside is that you can
easily create inconsistent ``DUK_USE_xxx`` flags, the customization header
will be version specific, and you need to peek into Duktape internals to
know what defines to tweak.

Using DUK_OPT_PANIC_HANDLER
===========================

The default panic handler will print an error message to stdout unless I/O is
disabled by ``DUK_OPT_NO_FILE_IO``.  It will then call ``abort()`` or cause a
segfault if ``DUK_OPT_SEGFAULT_ON_PANIC`` is defined.

You can override the entire panic handler by defining
``DUK_OPT_PANIC_HANDLER``.  For example, you could add the following to your
compiler options::

    '-DDUK_OPT_PANIC_HANDLER(code,msg)={printf("*** %d:%s\n",(code),(msg));abort();}'

You can also use::

    '-DDUK_OPT_PANIC_HANDLER(code,msg)={my_panic_handler((code),(msg))}'

which calls your custom handler::

    void my_panic_handler(int code, const char *msg) {
        /* Your panic handling.  Must not return. */
    }

The ``DUK_OPT_PANIC_HANDLER`` macro is used internally by Duktape, so your
panic handler function needs to be declared for Duktape compilation to avoid
compiler warnings about undeclared functions.  You can "inject" a declaration
for your function into Duktape compilation with::

    '-DDUK_OPT_DECLARE=extern void my_panic_handler(int code, const char *msg);'

After this you might still get a compilation warning like "a noreturn function
must not return" as the compiler doesn't know your panic handler doesn't
return.  You can fix this by either using a (compiler specific) "noreturn"
declaration, or by modifying the panic handler macro to something like::

    '-DDUK_OPT_PANIC_HANDLER(code,msg)={my_panic_handler((code),(msg));abort()}'

As ``abort()`` is automatically a "noreturn" function the panic macro body
can no longer return.  Duktape always includes ``stdlib.h`` which provides
the ``abort()`` prototype so no additional include files are needed.

Memory management alternatives
==============================

There are three supported memory management alternatives:

* **Reference counting and mark-and-sweep (default)**: heap objects are
  freed immediately when they become unreachable except for objects
  participating in unreachable reference cycles.  Such objects are freed by
  a periodic voluntary, stop the world mark-and-sweep collection.
  Mark-and-sweep is also used as the emergency garbage collector if memory
  allocation fails.

* **Reference counting only**: reduces code footprint and eliminates garbage
  collection pauses, but objects in unreachable reference cycles are not
  collected until the Duktape heap is destroyed.  This alternative is not
  recommended unless the reference cycles are not an issue.  See notes below.

* **Mark-and-sweep only**: reduces code footprint and memory footprint (heap
  headers don't need to store a reference count), but there is more memory
  usage variance than in the default case.  The frequency of voluntary, stop
  the world mark-and-sweep collections is also higher than in the default
  case where reference counting is expected to handle almost all memory
  management.

When using only reference counting it is important to avoid creating
unreachable reference cycles.  Reference cycles are usually easy to avoid in
application code e.g. by using only forward pointers in data structures.  Even
if reference cycles are necessary, garbage collection can be allowed to work
simply by breaking the cycles before deleting the final references to such objects.
For example, if you have a tree structure where nodes maintain references to
both children and parents (creating reference cycles for each node) you could
walk the tree and set the parent reference to ``null`` before deleting
the final reference to the tree.

Unfortunately every Ecmascript function instance is required to be in a
reference loop with an automatic prototype object created for the function.
You can break this loop manually if you wish.  For internal technical reasons,
named function expressions are also in a reference loop; this loop cannot be
broken from user code and only mark-and-sweep can collect such functions.
See `Limitations <http://duktape.org/guide.html#limitations>`_.

Development notes
=================

This section only applies if you customize Duktape internals and wish to
submit a patch to be included in the mainline distribution.

Adding new feature options
--------------------------

* Add a descriptive ``DUK_OPT_xxx`` for the custom feature.  The custom
  feature should only be enabled if the feature option is explicitly given.

* Modify ``duk_features.h.in`` to detect your custom feature option and define
  appropriate internal ``DUK_USE_xxx`` define(s).  Conflicts with other
  features should be detected.  Code outside ``duk_features.h.in`` should only
  listen to ``DUK_USE_xxx`` defines so that the resolution process is fully
  contained in ``duk_features.h.in``.

Removing feature options
------------------------

* If the feature option has been a part of a stable release, add a check
  for it in ``duk_feature_sanity.h.in``.  If the option is present, the
  build should error out with a deprecation notice.  This is preferable to
  silently removing an option a user may be depending on.


text:
title: How to Calculate the Margin of Error for a Sample Proportion
localeTitle: Como calcular a margem de erro para uma proporção de amostra
---
## Como calcular a margem de erro para uma proporção de amostra

Este é um esboço. [Ajude nossa comunidade a expandi-lo](https://github.com/freecodecamp/guides/tree/master/src/pages/mathematics/how-to-calculate-the-margin-of-error-for-a-sample-proportion/index.md) .

[Este guia de estilo rápido ajudará a garantir que sua solicitação de recebimento seja aceita](https://github.com/freecodecamp/guides/blob/master/README.md) .

#### Mais Informações:

redpajama_set_name: RedPajamaGithub


text:
require 'spec_helper'

describe AbAdmin::Concerns::Utilities do
  describe 'token generation' do
    it 'generate uniq token' do
      expect(Product.generate_token(:token)).not_to be_blank
    end

    it 'generate uniq token' do
      product = build(:product)
      expect(product.generate_token(:token)).not_to be_blank
    end

    it 'generate uniq token' do
      product = create(:product)
      expect(product.generate_token(:token)).not_to be_blank
    end
  end

  describe '#ensure_token' do
    it 'store generated token' do
      product = create(:product)
      product.ensure_token(:token)
      expect(product.reload.token).not_to be_blank
    end

    it 'no db call on new record' do
      product = build(:product)
      expect(product).not_to receive(:update_column)
      product.ensure_token(:token)
    end

    it 'return existing token' do
      product = build(:product, token: 'abcd')
      expect(product).not_to receive(:generate_token)
      expect(product.ensure_token(:token)).to eq 'abcd'
    end
  end

  describe '#update_counter_column' do
    it 'update counters by sql' do
      collection = create(:collection)
      2.times { create(:product, collection: collection) }
      expect{
        Collection.update_counter_column(:products_count, :products)
      }.to change{ collection.reload.products_count }.from(0).to(2)
    end

    it 'with assoc conditions' do
      collection = create(:collection)
      create(:product, collection: collection, is_visible: false)
      create(:product, collection: collection, is_visible: true)
      expect{
        Collection.update_counter_column(:visible_products_count, :visible_products)
      }.to change{ collection.reload.visible_products_count }.from(0).to(1)
    end

    it 'consider default scope' do
      collection = create(:collection)
      create(:product, collection: collection, is_visible: true)
      create(:product, collection: collection, is_visible: true, is_deleted: true)
      expect{
        Collection.update_counter_column(:visible_products_count, :visible_products)
      }.to change{ collection.reload.visible_products_count }.from(0).to(1)
    end

    context 'has_many through' do
      it 'update counters by sql' do
        catalogue = create(:catalogue)
        2.times { create(:product, catalogues: [catalogue]) }
        expect {
          Catalogue.update_counter_column(:products_count, :products)
        }.to change { catalogue.reload.products_count }.from(0).to(2)
      end

      it 'with assoc conditions' do
        catalogue = create(:catalogue)
        2.times { create(:product, catalogues: [catalogue], is_visible: false) }
        2.times { create(:product, catalogues: [catalogue], is_visible: true) }
        expect {
          Catalogue.update_counter_column(:visible_products_count, :visible_products)
        }.to change { catalogue.reload.visible_products_count }.from(0).to(2)
      end
    end
  end
end


text:
package com.github.tweets.gateway.github

import com.github.tweets.common.GitHubProjectInfo
import org.mockito.Mockito
import org.scalatest.FunSuite
import org.scalatest.mock.MockitoSugar
import org.springframework.web.client.RestTemplate

class GitHubAPIGatewayImplTest extends FunSuite with MockitoSugar {
  implicit val restTemplate = mock[RestTemplate]

  val projectInfo = mock[GitHubProjectInfo]
  val projectsCollection = GitHubProjectInfoCollectionWrapper(List.fill(15)(projectInfo))

  val gateway = new GitHubAPIGatewayImpl

  test("should create appropriate request, execute it and fetch top 10 projects") {
    assert(projectsCollection.items.size === 15)

    Mockito.when(
      restTemplate.getForObject("https://api.github.com/search/repositories?q=word&sort=stars", classOf[GitHubProjectInfoCollectionWrapper])
    ).thenReturn(projectsCollection)
    val result = gateway.fetchTopProjects("word")

    assert(result === List.fill(10)(projectInfo))

    Mockito.verify(restTemplate)
      .getForObject("https://api.github.com/search/repositories?q=word&sort=stars", classOf[GitHubProjectInfoCollectionWrapper])
  }

}


text:
module Spree
  module Admin
    class ProductGroupsController < ResourceController
      before_filter :patch_params, :only => [:update]

      def preview
        @product_group = ProductGroup.new(params[:product_group])
        @product_group.name = "for_preview"
        respond_with(@product_group) { |format| format.html { render :partial => 'preview', :layout => false } }
      end

      protected

        def find_resource
          ProductGroup.find_by_permalink!(params[:id])
        end

        def location_after_save
          edit_admin_product_group_path(@product_group)
        end

        def collection
          params[:q] ||= {}
          params[:q][:sort] ||= "name.asc"
          @search = super.search(params[:q])
          @collection = @search.result(:distinct => true).page(params[:page]).per(Spree::Config[:admin_pgroup_per_page])
        end

      private

        # Consolidate argument arrays for nested product_scope attributes
        # Necessary for product scopes with multiple arguments
        def patch_params
          if params["product_group"] and params["product_group"]["product_scopes_attributes"].is_a?(Array)
            params["product_group"]["product_scopes_attributes"] = params["product_group"]["product_scopes_attributes"].group_by {|a| a["id"]}.map do |scope_id, attrs|
              a = { "id" => scope_id, "arguments" => attrs.map{|a| a["arguments"] }.flatten }
              if name = attrs.first["name"]
                a["name"] = name
              end
              a
            end
          end
        end

    end
  end
end


text:
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information.

using Microsoft.CodeAnalysis.Options;

namespace Microsoft.CodeAnalysis.Diagnostics;

// TODO: move to LSP layer
internal static class IdeAnalyzerOptionsStorage
{
    public static IdeAnalyzerOptions GetIdeAnalyzerOptions(this IGlobalOptionService globalOptions, string language)
        => new(
            CrashOnAnalyzerException: globalOptions.GetOption(CrashOnAnalyzerException),
            FadeOutUnusedImports: globalOptions.GetOption(FadeOutUnusedImports, language),
            FadeOutUnreachableCode: globalOptions.GetOption(FadeOutUnreachableCode, language),
            ReportInvalidPlaceholdersInStringDotFormatCalls: globalOptions.GetOption(ReportInvalidPlaceholdersInStringDotFormatCalls, language),
            ReportInvalidRegexPatterns: globalOptions.GetOption(ReportInvalidRegexPatterns, language),
            ReportInvalidJsonPatterns: globalOptions.GetOption(ReportInvalidJsonPatterns, language),
            DetectAndOfferEditorFeaturesForProbableJsonStrings: globalOptions.GetOption(DetectAndOfferEditorFeaturesForProbableJsonStrings, language));

    // for testing only
    internal static void SetIdeAnalyzerOptions(this IGlobalOptionService globalOptions, string language, IdeAnalyzerOptions options)
    {
        globalOptions.SetGlobalOption(new OptionKey((IOption)CrashOnAnalyzerException), options.CrashOnAnalyzerException);
        globalOptions.SetGlobalOption(new OptionKey((IOption)FadeOutUnusedImports, language), options.FadeOutUnusedImports);
        globalOptions.SetGlobalOption(new OptionKey((IOption)FadeOutUnreachableCode, language), options.FadeOutUnreachableCode);
        globalOptions.SetGlobalOption(new OptionKey((IOption)ReportInvalidPlaceholdersInStringDotFormatCalls, language), options.ReportInvalidPlaceholdersInStringDotFormatCalls);
        globalOptions.SetGlobalOption(new OptionKey((IOption)ReportInvalidRegexPatterns, language), options.ReportInvalidRegexPatterns);
        globalOptions.SetGlobalOption(new OptionKey((IOption)ReportInvalidJsonPatterns, language), options.ReportInvalidJsonPatterns);
        globalOptions.SetGlobalOption(new OptionKey((IOption)DetectAndOfferEditorFeaturesForProbableJsonStrings, language), options.DetectAndOfferEditorFeaturesForProbableJsonStrings);
    }

    public static readonly Option2<bool> CrashOnAnalyzerException = new(
        "InternalDiagnosticsOptions", "CrashOnAnalyzerException", IdeAnalyzerOptions.Default.CrashOnAnalyzerException,
        storageLocation: new LocalUserProfileStorageLocation(@"Roslyn\Internal\Diagnostics\CrashOnAnalyzerException"));

    public static readonly PerLanguageOption2<bool> FadeOutUnusedImports = new(
        "FadingOptions", "FadeOutUnusedImports", IdeAnalyzerOptions.Default.FadeOutUnusedImports,
        storageLocation: new RoamingProfileStorageLocation($"TextEditor.%LANGUAGE%.Specific.FadeOutUnusedImports"));

    public static readonly PerLanguageOption2<bool> FadeOutUnreachableCode = new(
        "FadingOptions", "FadeOutUnreachableCode", IdeAnalyzerOptions.Default.FadeOutUnreachableCode,
        storageLocation: new RoamingProfileStorageLocation($"TextEditor.%LANGUAGE%.Specific.FadeOutUnreachableCode"));

    public static PerLanguageOption2<bool> ReportInvalidPlaceholdersInStringDotFormatCalls =
        new("ValidateFormatStringOption",
            "ReportInvalidPlaceholdersInStringDotFormatCalls",
            IdeAnalyzerOptions.Default.ReportInvalidPlaceholdersInStringDotFormatCalls,
            storageLocation: new RoamingProfileStorageLocation("TextEditor.%LANGUAGE%.Specific.WarnOnInvalidStringDotFormatCalls"));

    public static PerLanguageOption2<bool> ReportInvalidRegexPatterns =
        new("RegularExpressionsOptions",
            "ReportInvalidRegexPatterns",
            IdeAnalyzerOptions.Default.ReportInvalidRegexPatterns,
            storageLocation: new RoamingProfileStorageLocation("TextEditor.%LANGUAGE%.Specific.ReportInvalidRegexPatterns"));

    public static PerLanguageOption2<bool> ReportInvalidJsonPatterns =
        new("JsonFeatureOptions",
            "ReportInvalidJsonPatterns",
            defaultValue: IdeAnalyzerOptions.Default.ReportInvalidJsonPatterns,
            storageLocation: new RoamingProfileStorageLocation("TextEditor.%LANGUAGE%.Specific.ReportInvalidJsonPatterns"));

    public static PerLanguageOption2<bool> DetectAndOfferEditorFeaturesForProbableJsonStrings =
        new("JsonFeatureOptions",
            "DetectAndOfferEditorFeaturesForProbableJsonStrings",
            defaultValue: IdeAnalyzerOptions.Default.DetectAndOfferEditorFeaturesForProbableJsonStrings,
            storageLocation: new RoamingProfileStorageLocation("TextEditor.%LANGUAGE%.Specific.DetectAndOfferEditorFeaturesForProbableJsonStrings"));
}


text: Rails.application.config.session_store :cookie_store, key: '_Achievemintz_session'


text:
///////////////////////////////////////////////////////////////////////////////
// EASTL/bitset.h
//
// Written and maintained by Paul Pedriana - 2005.
///////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////
// This file implements a bitset much like the C++ std::bitset class.
// The primary distinctions between this list and std::bitset are:
//    - bitset is more efficient than some other std::bitset implementations,
//    - bitset is savvy to an environment that doesn't have exception handling,
//      as is sometimes the case with console or embedded environments.
//    - bitset is savvy to environments in which 'unsigned long' is not the
//      most efficient integral data type. std::bitset implementations use
//      unsigned long, even if it is an inefficient integer type.
//    - bitset removes as much function calls as practical, in order to allow
//      debug builds to run closer in speed and code footprint to release builds.
//    - bitset doesn't support string functionality. We can add this if
//      it is deemed useful.
//
///////////////////////////////////////////////////////////////////////////////

#ifndef EASTL_BITSET_H
#define EASTL_BITSET_H

#include <EASTL/internal/config.h>
#include <EASTL/algorithm.h>

#ifdef _MSC_VER
    #pragma warning(push, 0)
#endif
#include <stddef.h>
#ifdef __MWERKS__
    #include <../Include/string.h> // Force the compiler to use the std lib header.
#else
    #include <string.h>
#endif
#ifdef _MSC_VER
    #pragma warning(pop)
#endif

#if EASTL_EXCEPTIONS_ENABLED
    #ifdef _MSC_VER
        #pragma warning(push, 0)
    #endif
    #include <stdexcept> // std::out_of_range, std::length_error.
    #ifdef _MSC_VER
        #pragma warning(pop)
    #endif
#endif

#if defined(_MSC_VER)
    #pragma warning(push)
    #pragma warning(disable: 4127)  // Conditional expression is constant
#elif defined(__SNC__)
    #pragma control %push diag
    #pragma diag_suppress=187       // Pointless comparison of unsigned integer with zero
#endif

namespace eastl
{

    /// BitsetWordType
    ///
    /// Defines the integral data type used by bitset.
    /// The C++ standard specifies that the std::bitset word type be unsigned long,
    /// but that isn't necessarily the most efficient data type for the given platform.
    /// We can follow the standard and be potentially less efficient or we can do what
    /// is more efficient but less like the C++ std::bitset.
    ///
    #if(EA_PLATFORM_WORD_SIZE == 4)
        typedef uint32_t BitsetWordType;
        const   uint32_t kBitsPerWord      = 32;
        const   uint32_t kBitsPerWordMask  = 31;
        const   uint32_t kBitsPerWordShift =  5;
    #else
        typedef uint64_t BitsetWordType;
        const   uint32_t kBitsPerWord      = 64;
        const   uint32_t kBitsPerWordMask  = 63;
        const   uint32_t kBitsPerWordShift =  6;
    #endif

    /// BITSET_WORD_COUNT
    ///
    /// Defines the number of words we use, based on the number of bits.
    ///
    #if !defined(__GNUC__) || (__GNUC__ >= 3) // GCC 2.x can't handle the simpler declaration below.
        #define BITSET_WORD_COUNT(nBitCount) (N == 0 ? 1 : ((N - 1) / (8 * sizeof(BitsetWordType)) + 1))
    #else
        #define BITSET_WORD_COUNT(nBitCount) ((N - 1) / (8 * sizeof(BitsetWordType)) + 1)
    #endif

    /// BitsetBase
    ///
    /// This is a default implementation that works for any number of words.
    ///
    template <size_t NW> // Templated on the number of words used to hold the bitset.
    struct BitsetBase
    {
        typedef BitsetWordType word_type;
        typedef BitsetBase<NW> this_type;
      #if EASTL_BITSET_SIZE_T
        typedef size_t         size_type;
      #else
        typedef eastl_size_t   size_type;
      #endif

    public:
        word_type mWord[NW];

    public:
        BitsetBase();
        BitsetBase(uint32_t value);

        void operator&=(const this_type& x);
        void operator|=(const this_type& x);
        void operator^=(const this_type& x);

        void operator<<=(size_type n);
        void operator>>=(size_type n);

        void flip();
        void set();
        void set(size_type i, bool value);
        void reset();

        bool operator==(const this_type& x) const;

        bool      any() const;
        size_type count() const;

        unsigned long to_ulong() const;

        word_type& DoGetWord(size_type i);
        word_type  DoGetWord(size_type i) const;

        size_type DoFindFirst() const;
        size_type DoFindNext(size_type last_find) const;

        size_type DoFindLast() const;
        size_type DoFindPrev(size_type last_find) const;

    }; // class BitsetBase

    /// BitsetBase<1>
    ///
    /// This is a specialization for a bitset that fits within one word.
    ///
    template <>
    struct BitsetBase<1>
    {
        typedef BitsetWordType word_type;
        typedef BitsetBase<1>  this_type;
      #if EASTL_BITSET_SIZE_T
        typedef size_t         size_type;
      #else
        typedef eastl_size_t   size_type;
      #endif

    public:
        word_type mWord[1]; // Defined as an array of 1 so that bitset can treat this BitsetBase like others.

    public:
        BitsetBase();
        BitsetBase(uint32_t value);

        void operator&=(const this_type& x);
        void operator|=(const this_type& x);
        void operator^=(const this_type& x);

        void operator<<=(size_type n);
        void operator>>=(size_type n);

        void flip();
        void set();
        void set(size_type i, bool value);
        void reset();

        bool operator==(const this_type& x) const;

        bool      any() const;
        size_type count() const;

        unsigned long to_ulong() const;

        word_type& DoGetWord(size_type);
        word_type  DoGetWord(size_type) const;

        size_type DoFindFirst() const;
        size_type DoFindNext(size_type last_find) const;

        size_type DoFindLast() const;
        size_type DoFindPrev(size_type last_find) const;

    }; // BitsetBase<1>

    /// BitsetBase<2>
    ///
    /// This is a specialization for a bitset that fits within two words.
    /// The difference here is that we avoid branching (ifs and loops).
    ///
    template <>
    struct BitsetBase<2>
    {
        typedef BitsetWordType word_type;
        typedef BitsetBase<2>  this_type;
      #if EASTL_BITSET_SIZE_T
        typedef size_t         size_type;
      #else
        typedef eastl_size_t   size_type;
      #endif

    public:
        word_type mWord[2];

    public:
        BitsetBase();
        BitsetBase(uint32_t value);

        void operator&=(const this_type& x);
        void operator|=(const this_type& x);
        void operator^=(const this_type& x);

        void operator<<=(size_type n);
        void operator>>=(size_type n);

        void flip();
        void set();
        void set(size_type i, bool value);
        void reset();

        bool operator==(const this_type& x) const;

        bool      any() const;
        size_type count() const;

        unsigned long to_ulong() const;

        word_type& DoGetWord(size_type);
        word_type  DoGetWord(size_type) const;

        size_type DoFindFirst() const;
        size_type DoFindNext(size_type last_find) const;

        size_type DoFindLast() const;
        size_type DoFindPrev(size_type last_find) const;

    }; // BitsetBase<2>

    /// bitset
    ///
    /// Implements a bitset much like the C++ std::bitset.
    ///
    /// As of this writing we don't have an implementation of bitset<0>,
    /// as it is deemed an academic exercise that nobody should actually
    /// use and it would increase code space.
    ///
    /// Note: bitset shifts of a magnitude >= sizeof(BitsetWordType)
    /// (e.g. shift of 32 on a 32 bit system) are not guaranteed to work
    /// properly. This is because some systems (e.g. Intel x86) take the
    /// shift value and mod it to the word size and thus a shift of 32
    /// can become a shift of 0 on a 32 bit system. We don't attempt to
    /// resolve this behaviour in this class because doing so would lead
    /// to a less efficient implementation and the vast majority of the
    /// time the user doesn't do shifts of >= word size. You can work
    /// around this by implementing a shift of 32 as two shifts of 16.
    ///
    template <size_t N>
    class bitset : private BitsetBase<BITSET_WORD_COUNT(N)>
    {
    public:
        typedef BitsetBase<BITSET_WORD_COUNT(N)>    base_type;
        typedef bitset<N>                           this_type;
        typedef BitsetWordType                      word_type;
        typedef typename base_type::size_type       size_type;

        enum
        {
            kSize      = N,
            kWordCount = BITSET_WORD_COUNT(N),
            kNW        = kWordCount             // This name is deprecated.
        };

        using base_type::mWord;
        using base_type::DoGetWord;
        using base_type::DoFindFirst;
        using base_type::DoFindNext;
        using base_type::DoFindLast;
        using base_type::DoFindPrev;

    public:
        /// reference
        ///
        /// A reference is a reference to a specific bit in the bitset.
        /// The C++ standard specifies that this be a nested class,
        /// though it is not clear if a non-nested reference implementation
        /// would be non-conforming.
        ///
        class reference
        {
        protected:
            friend class bitset;

            word_type* mpBitWord;
            size_type  mnBitIndex;

            reference(){} // The C++ standard specifies that this is private.

        public:
            reference(const bitset& x, size_type i);

            reference& operator=(bool value);
            reference& operator=(const reference& x);

            bool operator~() const;
            operator bool() const // Defined inline because CodeWarrior fails to be able to compile it outside.
               { return (*mpBitWord & (static_cast<word_type>(1) << (mnBitIndex & kBitsPerWordMask))) != 0; }

            reference& flip();
        };

    public:
        friend class reference;

        bitset();
        bitset(uint32_t value);

        // We don't define copy constructor and operator= because
        // the compiler-generated versions will suffice.

        this_type& operator&=(const this_type& x);
        this_type& operator|=(const this_type& x);
        this_type& operator^=(const this_type& x);

        this_type& operator<<=(size_type n);
        this_type& operator>>=(size_type n);

        this_type& set();
        this_type& set(size_type i, bool value = true);

        this_type& reset();
        this_type& reset(size_type i);

        this_type& flip();
        this_type& flip(size_type i);
        this_type  operator~() const;

        reference operator[](size_type i);
        bool      operator[](size_type i) const;

        const word_type* data() const;
        word_type*       data();

        unsigned long to_ulong() const;

        size_type count() const;
        size_type size() const;

        bool operator==(const this_type& x) const;
        bool operator!=(const this_type& x) const;

        bool test(size_type i) const;
        bool any() const;
        bool none() const;

        this_type operator<<(size_type n) const;
        this_type operator>>(size_type n) const;

        // Finds the index of the first "on" bit, returns kSize if none are set.
        size_type find_first() const;

        // Finds the index of the next "on" bit after last_find, returns kSize if none are set.
        size_type find_next(size_type last_find) const;

        // Finds the index of the last "on" bit, returns kSize if none are set.
        size_type find_last() const;

        // Finds the index of the last "on" bit before last_find, returns kSize if none are set.
        size_type find_prev(size_type last_find) const;

    }; // bitset

    /// BitsetCountBits
    ///
    /// This is a fast trick way to count bits without branches nor memory accesses.
    ///
    #if(EA_PLATFORM_WORD_SIZE == 4)
        inline uint32_t BitsetCountBits(uint32_t x)
        {
            x = x - ((x >> 1) & 0x55555555);
            x = (x & 0x33333333) + ((x >> 2) & 0x33333333);
            x = (x + (x >> 4)) & 0x0F0F0F0F;
            return (uint32_t)((x * 0x01010101) >> 24); //-V2005
        }
    #else
        inline uint32_t BitsetCountBits(uint64_t x)
        {
            // GCC 3.x's implementation of UINT64_C is broken and fails to deal with
            // the code below correctly. So we make a workaround for it. Earlier and
            // later versions of GCC don't have this bug.
            #if defined(__GNUC__) && (__GNUC__ == 3)
                x = x - ((x >> 1) & 0x5555555555555555ULL);
                x = (x & 0x3333333333333333ULL) + ((x >> 2) & 0x3333333333333333ULL);
                x = (x + (x >> 4)) & 0x0F0F0F0F0F0F0F0FULL;
                return (uint32_t)((x * 0x0101010101010101ULL) >> 56);
            #else
                x = x - ((x >> 1) & UINT64_C(0x5555555555555555));
                x = (x & UINT64_C(0x3333333333333333)) + ((x >> 2) & UINT64_C(0x3333333333333333));
                x = (x + (x >> 4)) & UINT64_C(0x0F0F0F0F0F0F0F0F);
                return (uint32_t)((x * UINT64_C(0x0101010101010101)) >> 56);
            #endif
        }
    #endif

    // const static char kBitsPerUint16[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
    #define EASTL_BITSET_COUNT_STRING "\0\1\1\2\1\2\2\3\1\2\2\3\2\3\3\4"

    ///////////////////////////////////////////////////////////////////////////
    // BitsetBase
    //
    // We tried two forms of array access here:
    //     for(word_type *pWord(mWord), *pWordEnd(mWord + NW); pWord < pWordEnd; ++pWord)
    //         *pWord = ...
    // and
    //     for(size_t i = 0; i < NW; i++)
    //         mWord[i] = ...
    //
    // For our tests (~NW < 16), the latter (using []) access resulted in faster code.
    ///////////////////////////////////////////////////////////////////////////

    template <size_t NW>
    inline BitsetBase<NW>::BitsetBase()
    {
        reset();
    }

    template <size_t NW>
    inline BitsetBase<NW>::BitsetBase(uint32_t value)
    {
        // This implementation assumes that sizeof(value) <= sizeof(BitsetWordType).
        EASTL_CT_ASSERT(sizeof(value) <= sizeof(BitsetWordType));

        reset();
        mWord[0] = static_cast<word_type>(value);
    }

    template <size_t NW>
    inline void BitsetBase<NW>::operator&=(const this_type& x)
    {
        for(size_t i = 0; i < NW; i++)
            mWord[i] &= x.mWord[i];
    }

    template <size_t NW>
    inline void BitsetBase<NW>::operator|=(const this_type& x)
    {
        for(size_t i = 0; i < NW; i++)
            mWord[i] |= x.mWord[i];
    }

    template <size_t NW>
    inline void BitsetBase<NW>::operator^=(const this_type& x)
    {
        for(size_t i = 0; i < NW; i++)
            mWord[i] ^= x.mWord[i];
    }

    template <size_t NW>
    inline void BitsetBase<NW>::operator<<=(size_type n)
    {
        const size_type nWordShift = (size_type)(n >> kBitsPerWordShift); //-V2005

        if(nWordShift)
        {
            for(int i = (int)(NW - 1); i >= 0; --i) //-V2005
                mWord[i] = (nWordShift <= (size_type)i) ? mWord[i - nWordShift] : (word_type)0; //-V2005
        }

        if(n &= kBitsPerWordMask)
        {
            for(size_t i = (NW - 1); i > 0; --i)
                mWord[i] = (word_type)((mWord[i] << n) | (mWord[i - 1] >> (kBitsPerWord - n))); //-V2005
            mWord[0] <<= n;
        }

        // We let the parent class turn off any upper bits.
    }

    template <size_t NW>
    inline void BitsetBase<NW>::operator>>=(size_type n)
    {
        const size_type nWordShift = (size_type)(n >> kBitsPerWordShift); //-V2005

        if(nWordShift)
        {
            for(size_t i = 0; i < NW; ++i)
                mWord[i] = ((nWordShift < (NW - i)) ? mWord[i + nWordShift] : (word_type)0); //-V2005
        }

        if(n &= kBitsPerWordMask)
        {
            for(size_t i = 0; i < (NW - 1); ++i)
                mWord[i] = (word_type)((mWord[i] >> n) | (mWord[i + 1] << (kBitsPerWord - n))); //-V2005
            mWord[NW - 1] >>= n;
        }
    }

    template <size_t NW>
    inline void BitsetBase<NW>::flip()
    {
        for(size_t i = 0; i < NW; i++)
            mWord[i] = ~mWord[i];
        // We let the parent class turn off any upper bits.
    }

    template <size_t NW>
    inline void BitsetBase<NW>::set()
    {
        for(size_t i = 0; i < NW; i++)
            mWord[i] = ~static_cast<word_type>(0);
        // We let the parent class turn off any upper bits.
    }

    template <size_t NW>
    inline void BitsetBase<NW>::set(size_type i, bool value)
    {
        if(value)
            mWord[i >> kBitsPerWordShift] |=  (static_cast<word_type>(1) << (i & kBitsPerWordMask));
        else
            mWord[i >> kBitsPerWordShift] &= ~(static_cast<word_type>(1) << (i & kBitsPerWordMask));
    }

    template <size_t NW>
    inline void BitsetBase<NW>::reset()
    {
        if(NW > 16) // This is a constant expression and should be optimized away.
        {
            // This will be fastest if compiler intrinsic function optimizations are enabled.
            memset(mWord, 0, sizeof(mWord));
        }
        else
        {
            for(size_t i = 0; i < NW; i++)
                mWord[i] = 0;
        }
    }

    template <size_t NW>
    inline bool BitsetBase<NW>::operator==(const this_type& x) const
    {
        for(size_t i = 0; i < NW; i++)
        {
            if(mWord[i] != x.mWord[i])
                return false;
        }
        return true;
    }

    template <size_t NW>
    inline bool BitsetBase<NW>::any() const
    {
        for(size_t i = 0; i < NW; i++)
        {
            if(mWord[i])
                return true;
        }
        return false;
    }

    template <size_t NW>
    inline typename BitsetBase<NW>::size_type
    BitsetBase<NW>::count() const
    {
        size_type n = 0;

        for(size_t i = 0; i < NW; i++)
        {
            #if defined(__GNUC__) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 304) && !defined(__SNC__) && !defined(EA_PLATFORM_ANDROID) // GCC 3.4 or later
                #if(EA_PLATFORM_WORD_SIZE == 4)
                    n += (size_type)__builtin_popcountl(mWord[i]);
                #else
                    n += (size_type)__builtin_popcountll(mWord[i]);
                #endif
            #elif defined(__GNUC__) && (__GNUC__ < 3)
                n +=  BitsetCountBits(mWord[i]); // GCC 2.x compiler inexplicably blows up on the code below.
            #else
                for(word_type w = mWord[i]; w; w >>= 4)
                    n += EASTL_BITSET_COUNT_STRING[w & 0xF];

                // Version which seems to run slower in benchmarks:
                // n +=  BitsetCountBits(mWord[i]);
            #endif

        }
        return n;
    }

    template <size_t NW>
    inline unsigned long BitsetBase<NW>::to_ulong() const
    {
        #if EASTL_EXCEPTIONS_ENABLED
            for(size_t i = 1; i < NW; ++i)
            {
                if(mWord[i])
                    throw overflow_error("BitsetBase::to_ulong");
            }
        #endif
        return (unsigned long)mWord[0]; // Todo: We need to deal with the case whereby sizeof(word_type) < sizeof(unsigned long) //-V2005
    }

    template <size_t NW>
    inline typename BitsetBase<NW>::word_type&
    BitsetBase<NW>::DoGetWord(size_type i)
    {
        return mWord[i >> kBitsPerWordShift];
    }

    template <size_t NW>
    inline typename BitsetBase<NW>::word_type
    BitsetBase<NW>::DoGetWord(size_type i) const
    {
        return mWord[i >> kBitsPerWordShift];
    }

    #if(EA_PLATFORM_WORD_SIZE == 4)
        inline uint32_t GetFirstBit(uint32_t x)
        {
            if(x)
            {
                uint32_t n = 1;

                if((x & 0x0000FFFF) == 0) { n += 16; x >>= 16; }
                if((x & 0x000000FF) == 0) { n +=  8; x >>=  8; }
                if((x & 0x0000000F) == 0) { n +=  4; x >>=  4; }
                if((x & 0x00000003) == 0) { n +=  2; x >>=  2; }

                return (n - ((uint32_t)x & 1)); //-V2005
            }

            return 32;
        }
    #else
        inline uint32_t GetFirstBit(uint64_t x)
        {
            if(x)
            {
                uint32_t n = 1;

                if((x & 0xFFFFFFFF) == 0) { n += 32; x >>= 32; }
                if((x & 0x0000FFFF) == 0) { n += 16; x >>= 16; }
                if((x & 0x000000FF) == 0) { n +=  8; x >>=  8; }
                if((x & 0x0000000F) == 0) { n +=  4; x >>=  4; }
                if((x & 0x00000003) == 0) { n +=  2; x >>=  2; }

                return (n - ((uint32_t)x & 1));
            }

            return 64;
        }
    #endif

    template <size_t NW>
    inline typename BitsetBase<NW>::size_type
    BitsetBase<NW>::DoFindFirst() const
    {
        for(size_type word_index = 0; word_index < NW; ++word_index)
        {
            const size_type fbiw = GetFirstBit(mWord[word_index]);

            if(fbiw != kBitsPerWord)
                return (word_index * kBitsPerWord) + fbiw;
        }

        return (size_type)NW * kBitsPerWord; //-V2005
    }

    template <size_t NW>
    inline typename BitsetBase<NW>::size_type
    BitsetBase<NW>::DoFindNext(size_type last_find) const
    {
        // Start looking from the next bit.
        ++last_find;

        // Set initial state based on last find.
        size_type word_index = static_cast<size_type>(last_find >> kBitsPerWordShift);
        size_type bit_index  = static_cast<size_type>(last_find  & kBitsPerWordMask);

        // To do: There probably is a more elegant way to write looping below.
        if(word_index < NW)
        {
            // Mask off previous bits of the word so our search becomes a "find first".
            word_type this_word = mWord[word_index] & (~static_cast<word_type>(0) << bit_index);

            for(;;)
            {
                const size_type fbiw = GetFirstBit(this_word);

                if(fbiw != kBitsPerWord)
                    return (word_index * kBitsPerWord) + fbiw;

                if(++word_index < NW)
                    this_word = mWord[word_index];
                else
                    break;
            }
        }

        return (size_type)NW * kBitsPerWord; //-V2005
    }

    #if(EA_PLATFORM_WORD_SIZE == 4)
        inline uint32_t GetLastBit(uint32_t x)
        {
            if(x)
            {
                uint32_t n = 0;

                if(x & 0xFFFF0000) { n += 16; x >>= 16; }
                if(x & 0xFFFFFF00) { n +=  8; x >>=  8; }
                if(x & 0xFFFFFFF0) { n +=  4; x >>=  4; }
                if(x & 0xFFFFFFFC) { n +=  2; x >>=  2; }
                if(x & 0xFFFFFFFE) { n +=  1;           }

                return n;
            }

            return 32;
        }
    #else
        inline uint32_t GetLastBit(uint64_t x)
        {
            if(x)
            {
                uint32_t n = 0;

                if(x & UINT64_C(0xFFFFFFFF00000000)) { n += 32; x >>= 32; }
                if(x & 0xFFFF0000)                   { n += 16; x >>= 16; }
                if(x & 0xFFFFFF00)                   { n +=  8; x >>=  8; }
                if(x & 0xFFFFFFF0)                   { n +=  4; x >>=  4; }
                if(x & 0xFFFFFFFC)                   { n +=  2; x >>=  2; }
                if(x & 0xFFFFFFFE)                   { n +=  1;           }

                return n;
            }

            return 64;
        }
    #endif

    template <size_t NW>
    inline typename BitsetBase<NW>::size_type
    BitsetBase<NW>::DoFindLast() const
    {
        for(size_t word_index = (size_type)NW - 1; word_index < NW; --word_index) //-V2005
        {
            const size_type lbiw = GetLastBit(mWord[word_index]);

            if(lbiw != kBitsPerWord)
                return (word_index * kBitsPerWord) + lbiw;
        }

        return (size_type)NW * kBitsPerWord; //-V2005
    }

    template <size_t NW>
    inline typename BitsetBase<NW>::size_type
    BitsetBase<NW>::DoFindPrev(size_type last_find) const
    {
        if(last_find > 0)
        {
            // Set initial state based on last find.
            size_type word_index = static_cast<size_type>(last_find >> kBitsPerWordShift);
            size_type bit_index  = static_cast<size_type>(last_find  & kBitsPerWordMask);

            // Mask off subsequent bits of the word so our search becomes a "find last".
            word_type mask      = (~static_cast<word_type>(0) >> (kBitsPerWord - 1 - bit_index)) >> 1; // We do two shifts here because many CPUs ignore requests to shift 32 bit integers by 32 bits, which could be the case above.
            word_type this_word = mWord[word_index] & mask;

            for(;;)
            {
                const size_type lbiw = GetLastBit(this_word);

                if(lbiw != kBitsPerWord)
                    return (word_index * kBitsPerWord) + lbiw;

                if(word_index > 0)
                    this_word = mWord[--word_index];
                else
                    break;
            }
        }

        return (size_type)NW * kBitsPerWord; //-V2005
    }

    ///////////////////////////////////////////////////////////////////////////
    // BitsetBase<1>
    ///////////////////////////////////////////////////////////////////////////

    inline BitsetBase<1>::BitsetBase()
    {
        mWord[0] = 0;
    }

    inline BitsetBase<1>::BitsetBase(uint32_t value)
    {
        // This implementation assumes that sizeof(value) <= sizeof(BitsetWordType).
        EASTL_CT_ASSERT(sizeof(value) <= sizeof(BitsetWordType));

        mWord[0] = static_cast<word_type>(value);
    }

    inline void BitsetBase<1>::operator&=(const this_type& x)
    {
        mWord[0] &= x.mWord[0];
    }

    inline void BitsetBase<1>::operator|=(const this_type& x)
    {
        mWord[0] |= x.mWord[0];
    }

    inline void BitsetBase<1>::operator^=(const this_type& x)
    {
        mWord[0] ^= x.mWord[0];
    }

    inline void BitsetBase<1>::operator<<=(size_type n)
    {
        mWord[0] <<= n;
        // We let the parent class turn off any upper bits.
    }

    inline void BitsetBase<1>::operator>>=(size_type n)
    {
        mWord[0] >>= n;
    }

    inline void BitsetBase<1>::flip()
    {
        mWord[0] = ~mWord[0];
        // We let the parent class turn off any upper bits.
    }

    inline void BitsetBase<1>::set()
    {
        mWord[0] = ~static_cast<word_type>(0);
        // We let the parent class turn off any upper bits.
    }

    inline void BitsetBase<1>::set(size_type i, bool value)
    {
        if(value)
            mWord[0] |=  (static_cast<word_type>(1) << i);
        else
            mWord[0] &= ~(static_cast<word_type>(1) << i);
    }

    inline void BitsetBase<1>::reset()
    {
        mWord[0] = 0;
    }

    inline bool BitsetBase<1>::operator==(const this_type& x) const
    {
        return mWord[0] == x.mWord[0];
    }

    inline bool BitsetBase<1>::any() const
    {
        return mWord[0] != 0;
    }

    inline BitsetBase<1>::size_type
    BitsetBase<1>::count() const
    {
        #if defined(__GNUC__) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 304) && !defined(__SNC__) && !defined(EA_PLATFORM_ANDROID) // GCC 3.4 or later
            #if(EA_PLATFORM_WORD_SIZE == 4)
                return (size_type)__builtin_popcountl(mWord[0]);
            #else
                return (size_type)__builtin_popcountll(mWord[0]);
            #endif
        #elif defined(__GNUC__) && (__GNUC__ < 3)
            return BitsetCountBits(mWord[0]); // GCC 2.x compiler inexplicably blows up on the code below.
        #else
            size_type n = 0;
            for(word_type w = mWord[0]; w; w >>= 4)
                n += EASTL_BITSET_COUNT_STRING[w & 0xF];
            return n;
        #endif
    }

    inline unsigned long BitsetBase<1>::to_ulong() const
    {
        return static_cast<unsigned long>(mWord[0]);
    }

    inline BitsetBase<1>::word_type&
    BitsetBase<1>::DoGetWord(size_type)
    {
        return mWord[0];
    }

    inline BitsetBase<1>::word_type
    BitsetBase<1>::DoGetWord(size_type) const
    {
        return mWord[0];
    }

    inline BitsetBase<1>::size_type
    BitsetBase<1>::DoFindFirst() const
    {
        return GetFirstBit(mWord[0]);
    }

    inline BitsetBase<1>::size_type
    BitsetBase<1>::DoFindNext(size_type last_find) const
    {
        if(++last_find < kBitsPerWord)
        {
            // Mask off previous bits of word so our search becomes a "find first".
            const word_type this_word = mWord[0] & ((~static_cast<word_type>(0)) << last_find);

            return GetFirstBit(this_word);
        }

        return kBitsPerWord;
    }

    inline BitsetBase<1>::size_type
    BitsetBase<1>::DoFindLast() const
    {
        return GetLastBit(mWord[0]);
    }

    inline BitsetBase<1>::size_type
    BitsetBase<1>::DoFindPrev(size_type last_find) const
    {
        if(last_find > 0)
        {
            // Mask off previous bits of word so our search becomes a "find first".
            const word_type this_word = mWord[0] & ((~static_cast<word_type>(0)) >> (kBitsPerWord - last_find));

            return GetLastBit(this_word);
        }

        return kBitsPerWord;
    }

    ///////////////////////////////////////////////////////////////////////////
    // BitsetBase<2>
    ///////////////////////////////////////////////////////////////////////////

    inline BitsetBase<2>::BitsetBase()
    {
        mWord[0] = 0;
        mWord[1] = 0;
    }

    inline BitsetBase<2>::BitsetBase(uint32_t value)
    {
        // This implementation assumes that sizeof(value) <= sizeof(BitsetWordType).
        EASTL_CT_ASSERT(sizeof(value) <= sizeof(BitsetWordType));

        mWord[0] = static_cast<word_type>(value);
        mWord[1] = 0;
    }

    inline void BitsetBase<2>::operator&=(const this_type& x)
    {
        mWord[0] &= x.mWord[0];
        mWord[1] &= x.mWord[1];
    }

    inline void BitsetBase<2>::operator|=(const this_type& x)
    {
        mWord[0] |= x.mWord[0];
        mWord[1] |= x.mWord[1];
    }

    inline void BitsetBase<2>::operator^=(const this_type& x)
    {
        mWord[0] ^= x.mWord[0];
        mWord[1] ^= x.mWord[1];
    }

    inline void BitsetBase<2>::operator<<=(size_type n)
    {
        if(EASTL_UNLIKELY(n >= kBitsPerWord))   // parent expected to handle high bits and n >= 64
        {
            mWord[1] = mWord[0];
            mWord[0] = 0;
            n -= kBitsPerWord;
        }

        mWord[1] = (mWord[1] << n) | (mWord[0] >> (kBitsPerWord - n)); // Intentionally use | instead of +.
        mWord[0] <<= n;
        // We let the parent class turn off any upper bits.
    }

    inline void BitsetBase<2>::operator>>=(size_type n)
    {
        if(EASTL_UNLIKELY(n >= kBitsPerWord))   // parent expected to handle n >= 64
        {
            mWord[0] = mWord[1];
            mWord[1] = 0;
            n -= kBitsPerWord;
        }

        mWord[0] = (mWord[0] >> n) | (mWord[1] << (kBitsPerWord - n)); // Intentionally use | instead of +.
        mWord[1] >>= n;
    }

    inline void BitsetBase<2>::flip()
    {
        mWord[0] = ~mWord[0];
        mWord[1] = ~mWord[1];
        // We let the parent class turn off any upper bits.
    }

    inline void BitsetBase<2>::set()
    {
        mWord[0] = ~static_cast<word_type>(0);
        mWord[1] = ~static_cast<word_type>(0);
        // We let the parent class turn off any upper bits.
    }

    inline void BitsetBase<2>::set(size_type i, bool value)
    {
        if(value)
            mWord[i >> kBitsPerWordShift] |=  (static_cast<word_type>(1) << (i & kBitsPerWordMask));
        else
            mWord[i >> kBitsPerWordShift] &= ~(static_cast<word_type>(1) << (i & kBitsPerWordMask));
    }

    inline void BitsetBase<2>::reset()
    {
        mWord[0] = 0;
        mWord[1] = 0;
    }

    inline bool BitsetBase<2>::operator==(const this_type& x) const
    {
        return (mWord[0] == x.mWord[0]) && (mWord[1] == x.mWord[1]);
    }

    inline bool BitsetBase<2>::any() const
    {
        // Or with two branches: { return (mWord[0] != 0) || (mWord[1] != 0); }
        return (mWord[0] | mWord[1]) != 0;
    }

    inline BitsetBase<2>::size_type
    BitsetBase<2>::count() const
    {
        #if defined(__GNUC__) && (((__GNUC__ * 100) + __GNUC_MINOR__) >= 304) && !defined(__SNC__) && !defined(EA_PLATFORM_ANDROID) // GCC 3.4 or later
            #if(EA_PLATFORM_WORD_SIZE == 4)
                return (size_type)__builtin_popcountl(mWord[0])  + (size_type)__builtin_popcountl(mWord[1]);
            #else
                return (size_type)__builtin_popcountll(mWord[0]) + (size_type)__builtin_popcountll(mWord[1]);
            #endif

        #else
            return BitsetCountBits(mWord[0]) + BitsetCountBits(mWord[1]);
        #endif
    }

    inline unsigned long BitsetBase<2>::to_ulong() const
    {
        #if EASTL_EXCEPTIONS_ENABLED
            if(mWord[1])
                throw overflow_error("BitsetBase::to_ulong");
        #endif
        return (unsigned long)mWord[0]; // Todo: We need to deal with the case whereby sizeof(word_type) < sizeof(unsigned long) //-V2005
    }

    inline BitsetBase<2>::word_type&
    BitsetBase<2>::DoGetWord(size_type i)
    {
        return mWord[i >> kBitsPerWordShift];
    }

    inline BitsetBase<2>::word_type
    BitsetBase<2>::DoGetWord(size_type i) const
    {
        return mWord[i >> kBitsPerWordShift];
    }

    inline BitsetBase<2>::size_type
    BitsetBase<2>::DoFindFirst() const
    {
        size_type fbiw = GetFirstBit(mWord[0]);

        if(fbiw != kBitsPerWord)
            return fbiw;

        fbiw = GetFirstBit(mWord[1]);

        if(fbiw != kBitsPerWord)
            return kBitsPerWord + fbiw;

        return 2 * kBitsPerWord;
    }

    inline BitsetBase<2>::size_type
    BitsetBase<2>::DoFindNext(size_type last_find) const
    {
        // If the last find was in the first word, we must check it and then possibly the second.
        if(++last_find < (size_type)kBitsPerWord) //-V2005
        {
            // Mask off previous bits of word so our search becomes a "find first".
            word_type this_word = mWord[0] & ((~static_cast<word_type>(0)) << last_find);

            // Step through words.
            size_type fbiw = GetFirstBit(this_word);

            if(fbiw != kBitsPerWord)
                return fbiw;

            fbiw = GetFirstBit(mWord[1]);

            if(fbiw != kBitsPerWord)
                return kBitsPerWord + fbiw;
        }
        else if(last_find < (size_type)(2 * kBitsPerWord)) //-V2005
        {
            // The last find was in the second word, remove the bit count of the first word from the find.
            last_find -= kBitsPerWord;

            // Mask off previous bits of word so our search becomes a "find first".
            word_type this_word = mWord[1] & ((~static_cast<word_type>(0)) << last_find);

            const size_type fbiw = GetFirstBit(this_word);

            if(fbiw != kBitsPerWord)
                return kBitsPerWord + fbiw;
        }

        return 2 * kBitsPerWord;
    }

    inline BitsetBase<2>::size_type
    BitsetBase<2>::DoFindLast() const
    {
        size_type lbiw = GetLastBit(mWord[1]);

        if(lbiw != kBitsPerWord)
            return kBitsPerWord + lbiw;

        lbiw = GetLastBit(mWord[0]);

        if(lbiw != kBitsPerWord)
            return lbiw;

        return 2 * kBitsPerWord;
    }

    inline BitsetBase<2>::size_type
    BitsetBase<2>::DoFindPrev(size_type last_find) const
    {
        // If the last find was in the second word, we must check it and then possibly the first.
        if(last_find > (size_type)kBitsPerWord) //-V2005
        {
            // This has the same effect as last_find %= kBitsPerWord in our case.
            last_find -= kBitsPerWord;

            // Mask off previous bits of word so our search becomes a "find first".
            word_type this_word = mWord[1] & ((~static_cast<word_type>(0)) >> (kBitsPerWord - last_find));

            // Step through words.
            size_type lbiw = GetLastBit(this_word);

            if(lbiw != kBitsPerWord)
                return kBitsPerWord + lbiw;

            lbiw = GetLastBit(mWord[0]);

            if(lbiw != kBitsPerWord)
                return lbiw;
        }
        else if(last_find != 0)
        {
            // Mask off previous bits of word so our search becomes a "find first".
            word_type this_word = mWord[0] & ((~static_cast<word_type>(0)) >> (kBitsPerWord - last_find));

            const size_type lbiw = GetLastBit(this_word);

            if(lbiw != kBitsPerWord)
                return lbiw;
        }

        return 2 * kBitsPerWord;
    }

    ///////////////////////////////////////////////////////////////////////////
    // bitset::reference
    ///////////////////////////////////////////////////////////////////////////

    template <size_t N>
    inline bitset<N>::reference::reference(const bitset& x, size_type i)
        : mpBitWord(&const_cast<bitset&>(x).DoGetWord(i)),
          mnBitIndex(i & kBitsPerWordMask)
    {   // We have an issue here because the above is casting away the const-ness of the source bitset.
        // Empty
    }

    template <size_t N>
    inline typename bitset<N>::reference&
    bitset<N>::reference::operator=(bool value)
    {
        if(value)
            *mpBitWord |=  (static_cast<word_type>(1) << (mnBitIndex & kBitsPerWordMask));
        else
            *mpBitWord &= ~(static_cast<word_type>(1) << (mnBitIndex & kBitsPerWordMask));
        return *this;
    }

    template <size_t N>
    inline typename bitset<N>::reference&
    bitset<N>::reference::operator=(const reference& x)
    {
        if(*x.mpBitWord & (static_cast<word_type>(1) << (x.mnBitIndex & kBitsPerWordMask)))
            *mpBitWord |=  (static_cast<word_type>(1) << (mnBitIndex & kBitsPerWordMask));
        else
            *mpBitWord &= ~(static_cast<word_type>(1) << (mnBitIndex & kBitsPerWordMask));
        return *this;
    }

    template <size_t N>
    inline bool bitset<N>::reference::operator~() const
    {
        return (*mpBitWord & (static_cast<word_type>(1) << (mnBitIndex & kBitsPerWordMask))) == 0;
    }

    //Defined inline in the class because Metrowerks fails to be able to compile it here.
    //template <size_t N>
    //inline bitset<N>::reference::operator bool() const
    //{
    //    return (*mpBitWord & (static_cast<word_type>(1) << (mnBitIndex & kBitsPerWordMask))) != 0;
    //}

    template <size_t N>
    inline typename bitset<N>::reference&
    bitset<N>::reference::flip()
    {
        *mpBitWord ^= static_cast<word_type>(1) << (mnBitIndex & kBitsPerWordMask);
        return *this;
    }

    ///////////////////////////////////////////////////////////////////////////
    // bitset
    ///////////////////////////////////////////////////////////////////////////

    template <size_t N>
    inline bitset<N>::bitset()
        : base_type()
    {
        // Empty. The base class will set all bits to zero.
    }

    template <size_t N>
    inline bitset<N>::bitset(uint32_t value)
        : base_type(value)
    {
        if((N & kBitsPerWordMask) || (N == 0)) // If there are any high bits to clear... (If we didn't have this check, then the code below would do the wrong thing when N == 32.
            mWord[kNW - 1] &= ~(~static_cast<word_type>(0) << (N & kBitsPerWordMask)); // This clears any high unused bits.
    }

    template <size_t N>
    inline typename bitset<N>::this_type&
    bitset<N>::operator&=(const this_type& x)
    {
        base_type::operator&=(x);
        return *this;
    }

    template <size_t N>
    inline typename bitset<N>::this_type&
    bitset<N>::operator|=(const this_type& x)
    {
        base_type::operator|=(x);
        return *this;
    }

    template <size_t N>
    inline typename bitset<N>::this_type&
    bitset<N>::operator^=(const this_type& x)
    {
        base_type::operator^=(x);
        return *this;
    }

    template <size_t N>
    inline typename bitset<N>::this_type&
    bitset<N>::operator<<=(size_type n)
    {
        if(EASTL_LIKELY((intptr_t)n < (intptr_t)N)) //-V2005
        {
            base_type::operator<<=(n);
            if((N & kBitsPerWordMask) || (N == 0)) // If there are any high bits to clear... (If we didn't have this check, then the code below would do the wrong thing when N == 32.
                mWord[kNW - 1] &= ~(~static_cast<word_type>(0) << (N & kBitsPerWordMask)); // This clears any high unused bits. We need to do this so that shift operations proceed correctly.
        }
        else
            base_type::reset();
        return *this;
    }

    template <size_t N>
    inline typename bitset<N>::this_type&
    bitset<N>::operator>>=(size_type n)
    {
        if(EASTL_LIKELY(n < N))
            base_type::operator>>=(n);
        else
            base_type::reset();
        return *this;
    }

    template <size_t N>
    inline typename bitset<N>::this_type&
    bitset<N>::set()
    {
        base_type::set(); // This sets all bits.
        if((N & kBitsPerWordMask) || (N == 0)) // If there are any high bits to clear... (If we didn't have this check, then the code below would do the wrong thing when N == 32.
            mWord[kNW - 1] &= ~(~static_cast<word_type>(0) << (N & kBitsPerWordMask)); // This clears any high unused bits. We need to do this so that shift operations proceed correctly.
        return *this;
    }

    template <size_t N>
    inline typename bitset<N>::this_type&
    bitset<N>::set(size_type i, bool value)
    {
        if(i < N)
            base_type::set(i, value);

        #if EASTL_ASSERT_ENABLED
            if(EASTL_UNLIKELY(!(i < N)))
                EASTL_FAIL_MSG("bitset::set -- out of range");
        #endif

        #if EASTL_EXCEPTIONS_ENABLED
            else
                throw out_of_range("bitset::set");
        #endif
        return *this;
    }

    template <size_t N>
    inline typename bitset<N>::this_type&
    bitset<N>::reset()
    {
        base_type::reset();
        return *this;
    }

    template <size_t N>
    inline typename bitset<N>::this_type&
    bitset<N>::reset(size_type i)
    {
        if(EASTL_LIKELY(i < N))
            DoGetWord(i) &= ~(static_cast<word_type>(1) << (i & kBitsPerWordMask));

        #if EASTL_ASSERT_ENABLED
            if(EASTL_UNLIKELY(!(i < N)))
                EASTL_FAIL_MSG("bitset::reset -- out of range");
        #endif

        #if EASTL_EXCEPTIONS_ENABLED
            else
                throw out_of_range("bitset::reset");
        #endif
        return *this;
    }

    template <size_t N>
    inline typename bitset<N>::this_type&
    bitset<N>::flip()
    {
        base_type::flip();
        if((N & kBitsPerWordMask) || (N == 0)) // If there are any high bits to clear... (If we didn't have this check, then the code below would do the wrong thing when N == 32.
            mWord[kNW - 1] &= ~(~static_cast<word_type>(0) << (N & kBitsPerWordMask)); // This clears any high unused bits. We need to do this so that shift operations proceed correctly.
        return *this;
    }

    template <size_t N>
    inline typename bitset<N>::this_type&
    bitset<N>::flip(size_type i)
    {
        if(EASTL_LIKELY(i < N))
            DoGetWord(i) ^= (static_cast<word_type>(1) << (i & kBitsPerWordMask));

        #if EASTL_ASSERT_ENABLED
            if(EASTL_UNLIKELY(!(i < N)))
                EASTL_FAIL_MSG("bitset::flip -- out of range");
        #endif

        #if EASTL_EXCEPTIONS_ENABLED
            else
                throw out_of_range("bitset::flip");
        #endif
        return *this;
    }

    template <size_t N>
    inline typename bitset<N>::this_type
    bitset<N>::operator~() const
    {
        return this_type(*this).flip();
    }

    template <size_t N>
    inline typename bitset<N>::reference
    bitset<N>::operator[](size_type i)
    {
        #if EASTL_ASSERT_ENABLED
            if(EASTL_UNLIKELY(!(i < N)))
                EASTL_FAIL_MSG("bitset::operator[] -- out of range");
        #endif

        return reference(*this, i);
    }

    template <size_t N>
    inline bool bitset<N>::operator[](size_type i) const
    {
        #if EASTL_ASSERT_ENABLED
            if(EASTL_UNLIKELY(!(i < N)))
                EASTL_FAIL_MSG("bitset::operator[] -- out of range");
        #endif

        return (DoGetWord(i) & (static_cast<word_type>(1) << (i & kBitsPerWordMask))) != 0;
    }

    template <size_t N>
    inline const typename bitset<N>::word_type* bitset<N>::data() const
    {
        return base_type::mWord;
    }

    template <size_t N>
    inline typename bitset<N>::word_type* bitset<N>::data()
    {
        return base_type::mWord;
    }

    template <size_t N>
    inline unsigned long bitset<N>::to_ulong() const
    {
        return base_type::to_ulong();
    }

    template <size_t N>
    inline typename bitset<N>::size_type
    bitset<N>::count() const
    {
        return base_type::count();
    }

    template <size_t N>
    inline typename bitset<N>::size_type
    bitset<N>::size() const
    {
        return (size_type)N; //-V2005
    }

    template <size_t N>
    inline bool bitset<N>::operator==(const this_type& x) const
    {
        return base_type::operator==(x);
    }

    template <size_t N>
    inline bool bitset<N>::operator!=(const this_type& x) const
    {
        return !base_type::operator==(x);
    }

    template <size_t N>
    inline bool bitset<N>::test(size_type i) const
    {
        if(EASTL_LIKELY(i < N))
            return (DoGetWord(i) & (static_cast<word_type>(1) << (i & kBitsPerWordMask))) != 0;

        #if EASTL_ASSERT_ENABLED
            if(EASTL_UNLIKELY(!(i < N)))
                EASTL_FAIL_MSG("bitset::test -- out of range");
        #endif

        #if EASTL_EXCEPTIONS_ENABLED
            else
                throw out_of_range("bitset::test");
        #endif
        return false;
    }

    template <size_t N>
    inline bool bitset<N>::any() const
    {
        return base_type::any();
    }

    template <size_t N>
    inline bool bitset<N>::none() const
    {
        return !base_type::any();
    }

    template <size_t N>
    inline typename bitset<N>::this_type
    bitset<N>::operator<<(size_type n) const
    {
        return this_type(*this).operator<<=(n);
    }

    template <size_t N>
    inline typename bitset<N>::this_type
    bitset<N>::operator>>(size_type n) const
    {
        return this_type(*this).operator>>=(n);
    }

    template <size_t N>
    inline typename bitset<N>::size_type
    bitset<N>::find_first() const
    {
        const size_type i = base_type::DoFindFirst();

        if(i < (kNW * kBitsPerWord)) // This multiplication is a compile-time constant.
            return i;

        return kSize;
    }

    template <size_t N>
    inline typename bitset<N>::size_type
    bitset<N>::find_next(size_type last_find) const
    {
        const size_type i = base_type::DoFindNext(last_find);

        if(i < (kNW * kBitsPerWord))// This multiplication is a compile-time constant.
            return i;

        return kSize;
    }

    template <size_t N>
    inline typename bitset<N>::size_type
    bitset<N>::find_last() const
    {
        const size_type i = base_type::DoFindLast();

        if(i < (kNW * kBitsPerWord)) // This multiplication is a compile-time constant.
            return i;

        return kSize;
    }

    template <size_t N>
    inline typename bitset<N>::size_type
    bitset<N>::find_prev(size_type last_find) const
    {
        const size_type i = base_type::DoFindPrev(last_find);

        if(i < (kNW * kBitsPerWord))// This multiplication is a compile-time constant.
            return i;

        return kSize;
    }

    ///////////////////////////////////////////////////////////////////////////
    // global operators
    ///////////////////////////////////////////////////////////////////////////

    template <size_t N>
    inline bitset<N> operator&(const bitset<N>& a, const bitset<N>& b)
    {
        // We get betting inlining when we don't declare temporary variables.
        return bitset<N>(a).operator&=(b);
    }

    template <size_t N>
    inline bitset<N> operator|(const bitset<N>& a, const bitset<N>& b)
    {
        return bitset<N>(a).operator|=(b);
    }

    template <size_t N>
    inline bitset<N> operator^(const bitset<N>& a, const bitset<N>& b)
    {
        return bitset<N>(a).operator^=(b);
    }

} // namespace eastl

#if defined(_MSC_VER)
    #pragma warning(pop)
#elif defined(__SNC__)
    #pragma control %pop diag
#endif

#endif // Header include guard


text:
set -e

echo "#############################################################################################"
echo "############################# Test Ansible Vault Actions ... ################################"
echo "+-------------------------------------------------------------------------------------------+"
echo "|                      Encrypt screen.yml playbook with ansible-vault                       |"
echo "+-------------------------------------------------------------------------------------------+"
echo "| ansible-vault encrypt \                                                                   |"
echo "|   /etc/ansible/playbooks/screen.yml ---vault-password-file=/etc/ansible/vault.txt         |"
echo "|  -->                                                                                |"
echo "| st2 run ansible.vault.encrypt \                                                           |"
echo "|   vault_password_file=/etc/ansible/vault.txt files=/etc/ansible/playbooks/screen.yml      |"
echo "+-------------------------------------------------------------------------------------------+"
st2 run ansible.vault.encrypt vault_password_file=/etc/ansible/vault.txt files=/etc/ansible/playbooks/screen.yml

echo "+-------------------------------------------------------------------------------------------+"
echo "|    Run encrypted screen.yml playbook, which uninstalls 'screen' package on first node     |"
echo "+-------------------------------------------------------------------------------------------+"
echo "| ansible-playbook /etc/ansible/playbooks/screen.yml \                                      |"
echo "|   --vault-password-file=/etc/ansible/vault.txt --limit='nodes[0]'                         |"
echo "|  -->                                                                                |"
echo "| st2 run ansible.playbook cwd=/etc/ansible \                                               |"
echo "|   playbook=playbooks/screen.yml vault_password_file=vault.txt limit='nodes[0]'            |"
echo "+-------------------------------------------------------------------------------------------+"
st2 run ansible.playbook cwd=/etc/ansible playbook=playbooks/screen.yml vault_password_file=vault.txt limit='nodes[0]'

echo "+-------------------------------------------------------------------------------------------+"
echo "|                            Decrypt screen.yml playbook                                    |"
echo "+-------------------------------------------------------------------------------------------+"
echo "| ansible-vault decrypt \                                                                   |"
echo "|   /etc/ansible/playbooks/screen.yml ---vault-password-file=/etc/ansible/vault.txt         |"
echo "|  -->                                                                                |"
echo "| st2 run ansible.vault.decrypt \                                                           |"
echo "|   cwd=/etc/ansible vault_password_file=vault.txt files=playbooks/screen.yml               |"
echo "+-------------------------------------------------------------------------------------------+"
st2 run ansible.vault.decrypt cwd=/etc/ansible vault_password_file=vault.txt files=playbooks/screen.yml

echo "+-------------------------------------------------------------------------------------------+"
echo "|                  Replay decrypted screen.yml playbook on second node                      |"
echo "+-------------------------------------------------------------------------------------------+"
echo "| ansible-playbook /etc/ansible/playbooks/screen.yml --limit='nodes[1]'                     |"
echo "|  -->                                                                                |"
echo "| st2 run ansible.playbook playbook=/etc/ansible/playbooks/screen.yml limit='nodes[1]'      |"
echo "+-------------------------------------------------------------------------------------------+"
st2 run ansible.playbook playbook=/etc/ansible/playbooks/screen.yml limit='nodes[1]'

echo "Done!"
exit 0