// bsls_atomic.h                                                      -*-C++-*-
#ifndef INCLUDED_BSLS_ATOMIC
#define INCLUDED_BSLS_ATOMIC

#include <bsls_ident.h>
BSLS_IDENT("$Id: $")

//@PURPOSE: Provide types with atomic operations.
//
//@CLASSES:
//  bsls::AtomicBool: atomic boolean type
//  bsls::AtomicInt: atomic 32-bit integer type
//  bsls::AtomicInt64: atomic 64-bit integer type
//  bsls::AtomicUint: atomic 32-bit unsigned integer type
//  bsls::AtomicUint64: atomic 64-bit unsigned integer type
//  bsls::AtomicPointer: parameterized atomic pointer type
//
//@SEE_ALSO: bsls_atomicoperations
//
//@DESCRIPTION: This component provides classes with atomic operations for
// 'int', 'Int64', 'unsigned int', 'Uint64', 'pointer', and 'bool' types.
// These classes are based on atomic operations supplied by the
// 'bsls_atomicoperations' component.  The 'bsls::AtomicInt' and
// 'bsls::AtomicInt64' classes represent the corresponding atomic integer
// types, and provide overloaded operators and functions for common arithmetic
// operations.  The 'bsls::AtomicPointer' class represents the atomic pointer
// type, and provides atomic operations to manipulate and dereference a
// pointer.  The 'bsls::AtomicBool' class represents an atomic boolean type and
// provides operations to set and retrieve its value.
//
///Memory Order and Consistency Guarantees of Atomic Operations
///------------------------------------------------------------
// Atomic operations provided by this component ensure various memory ordering
// consistency guarantees.  Memory ordering guarantees of atomic operations are
// designed to ensure visibility and synchronization order of memory reads and
// writes between threads that perform atomic operations.  The operations on
// objects of the provided classes ensure the most strict consistency
// guarantee, sequential consistency (described below), unless explicitly
// qualified with a less strict consistency guarantee (i.e., Acquire, Release,
// Acquire/Release or Relaxed).
//
// This component implements memory order and consistency guarantees as defined
// in the C++ 2011 Standard (sections: [intro.multithreaded], [atomics.order]).
//
// The following memory ordering guarantees are supported:
//:
//: o relaxed - the operation does not provide any memory consistency guarantee
//:
//: o release - the operation performs a release operation on the affected
//:   memory location, thus making preceding regular memory writes of the
//:   calling thread visible to other threads through the atomic variable to
//:   which it is applied (generally available for operations that write to a
//:   memory location).
//:
//: o acquire - the operation performs an acquire operation on the affected
//:   memory location, thus making regular memory writes in other threads
//:   released through the atomic variable to which it is applied visible to
//:   the current thread (generally available for operations that read from a
//:   memory location).
//:
//: o acquire/release - the operation has both acquire and release semantics
//:   (generally available for operations that both read and write a memory
//:   location).
//:
//: o sequential consistency - the operation has both acquire and release
//:   guarantees, and further guarantees that all sequentially consistent
//:   operations performed by the process will be observed to occur in a single
//:   global total order (regardless of the thread from which they are
//:   observed).
//
///Acquire and Release Memory Consistency Guarantees
///- - - - - - - - - - - - - - - - - - - - - - - - -
// Operations providing acquire and release guarantees are essential to
// synchronizing the memory state between multiple threads.  For example,
// consider two threads, A and B, that perform store and load operations to
// shared memory locations.  Without any synchronization, store operations in
// thread A can be freely reordered with load operations in thread B, i.e,
// thread A can perform two store operations to two memory locations in a
// certain order and thread B can see those operations done in a different
// order due to such effects as: compiler or processor optimizations of store
// and load operations, and cache synchronization between processors and cores.
//
// However, stores in thread A can be ordered with loads in thread B using a
// combination of store-release and load-acquire operations.  A store-release
// operation in thread A followed by a load-acquire operation in thread B to
// the *same* *memory* *location* guarantees that thread B sees all other
// stores done in thread A prior to the store-release operation.  The
// store-release in thread A effectively synchronizes the memory state with the
// load-acquire in thread B.
//
// An acquire-release operation is a load-modify-store operation that, if
// performed in both threads A and B on the same memory location, synchronizes
// stores and loads between threads A and B in both directions.
//
///Sequential Consistency Memory Consistency Guarantee
///- - - - - - - - - - - - - - - - - - - - - - - - - -
// Finally, load and store operations with sequential consistency are
// guaranteed to performed in a global total order among all threads in the
// process.  To illustrate the total order, let's consider the so-called
// "independent reads of independent writes" example:
//..
//  bsls::AtomicInt x(0);
//  bsls::AtomicInt y(0);
//  int r1, r2, r3, r4;
//
//  void thread1() {
//      x = 1;  // sequential consistency store
//  }
//
//  void thread2() {
//      y = 1;  // sequential consistency store
//  }
//
//  void thread3() {
//      r1 = x;  // sequential consistency load
//      r2 = y;  // sequential consistency load
//  }
//
//  void thread4() {
//      r3 = y;  // sequential consistency load
//      r4 = x;  // sequential consistency load
//  }
//..
// Where 'threadN' functions are executed concurrently by different threads
// (note that values 'x' and 'y' are written by independent threads).
// Sequential consistency guarantees that if 'thread3' observes values 'x' and
// 'y' as 'r1 == 1 && r2 == 0', then 'thread4' can't observe values 'x' and 'y'
// in a different order, i.e., 'r3 == 1 && r4 == 0'.
//
///Usage
///-----
// This section illustrates intended use of this component.
//
///Example 1: Usage Statistics on a Thread Pool
/// - - - - - - - - - - - - - - - - - - - - - -
// This example demonstrates a common use of atomic integer types for
// statistics counters.  The program creates a series of threads to process
// transactions.  As each thread completes a transaction, it atomically
// increments the transaction counters.
//
// For this example, we assume the existence of the functions
// 'processNextTransaction', 'createWorkerThread', and 'waitAllThreads'.  The
// function 'createWorkerThread' spawns a new thread, which executes the
// 'workerThread' function.  'waitAllThreads' blocks until all the worker
// thread complete.
//
// First, we declare the shared counters (note that, in contrast to the raw
// types defined in 'bsls_atomicoperations', these atomic types are
// zero-initialized at construction):
//..
//  static bsls::AtomicInt64 transactionCount;
//  static bsls::AtomicInt64 successCount;
//  static bsls::AtomicInt64 failureCount;
//..
// Next, for each transaction processed, we atomically increment either the
// success or the failure counter as well as the total transaction count:
//..
//  static void workerThread(int *stop)
//  {
//      while (!(*stop)) {
//          if (processNextTransaction()) {
//              ++failureCount;
//          } else {
//              ++successCount;
//          }
//          ++transactionCount;
//      }
//  }
//..
// Finally, we write function, 'serverMain', that provides the overall control
// logic for the server.  This function spawns the threads and then waits for
// all work to be completed; when all of the threads have finished, this
// function returns normally:
//..
//  void serverMain()
//  {
//      const int num_threads = 10;
//      for (int i = 0; i < num_threads; ++i) {
//          createWorkerThread();
//      }
//      waitAllThreads();
//  }
//..
// Note that functions 'createWorkerThread' and 'waitAllThreads' can be
// implemented using any thread-support package.
//
///Example 2: Thread-Safe Counted Handle
///- - - - - - - - - - - - - - - - - - -
// The following example demonstrates the use of atomic integer operations to
// implement a thread-safe ref-counted handle similar to a shared pointer.
// Each handle (of type 'my_CountedHandle') maintains a pointer to a
// representation object, 'my_CountedHandleRep', which in turn, stores both a
// pointer to the managed object and a reference counter.
//
// Both the handle class and the representation class are template classes with
// two template parameters.  The template parameter, 'INSTANCE', represents the
// type of the "instance", or managed object.
//
// A representation object can be shared by several handle objects.  When a
// handle object is assigned to a second handle object, the address of the
// representation is copied to the second handle, and the reference count on
// the representation is atomically incremented.  When a handle releases its
// reference to the representation, it atomically decrements the reference
// count.  If the resulting reference count becomes 0 (and there are no more
// references to the object), the handle deletes the representation object and
// the representation object, in turn, deletes the managed object ('INSTANCE').
//
///Class 'my_CountedHandleRep'
///- - - - - - - - - - - - - -
// First, we define class 'my_CountedHandleRep'.  This class manages a single
// 'INSTANCE' object on behalf of multiple "handle" objects; since different
// "handle" objects may be active in different threads, class
// 'my_CountedHandleRep' must be (fully) thread-safe.  Specifically, methods
// 'increment' and 'decrement' must work atomically.
//
// The class declaration for 'my_CountedHandleRep' is identical to the same
// class in component 'bsls_atomicoperations', with a single exception: member
// 'd_count' is of type 'bsls::AtomicInt', rather than
// 'bsls::AtomicOperations::Int'.  Whereas 'bsls::AtomicOperations::Int' is
// merely a 'typedef' for a platform-specific data type to be used in atomic
// integer operations, 'bsls::AtomicInt' encapsulates those atomic operations
// as member functions and operator overloads.  Class 'my_CountedHandleRep'
// will benefit from this encapsulation: Its method implementations will be
// able to operate on 'd_count' as if it were a standard integer.
//
// Note that, as in the example in component 'bsls_atomicoperations', this rep
// class is intended to be used only by class 'my_CountedHandle', and thus all
// methods of class 'my_CountedHandleRep' are declared private, and 'friend'
// status is granted to class 'my_CountedHandle':
//..
//                          // =========================
//                          // class my_CountedHandleRep
//                          // =========================
//
//  template <class INSTANCE>
//  class my_CountedHandle;
//
//  template <class INSTANCE>
//  class my_CountedHandleRep {
//
//      // DATA
//      INSTANCE        *d_instance_p;   // address of managed instance
//      bsls::AtomicInt  d_count;        // number of active references
//
//      // FRIENDS
//      friend class my_CountedHandle<INSTANCE>;
//
//      // NOT IMPLEMENTED
//      my_CountedHandleRep(const my_CountedHandleRep&);
//      my_CountedHandleRep& operator=(const my_CountedHandleRep&);
//
//    private:
//      // PRIVATE CLASS METHODS
//      static void
//      deleteObject(my_CountedHandleRep<INSTANCE> *object);
//
//      // PRIVATE CREATORS
//      my_CountedHandleRep(INSTANCE *instance);
//      ~my_CountedHandleRep();
//
//      // PRIVATE MANIPULATORS
//      void increment();
//      int decrement();
//  };
//..
//
///Class 'my_CountedHandle'
///-  -  -  -  -  -  -  - -
// Then, we create class 'my_CountedHandle' that provides an individual handle
// to the shared, reference-counted object.  Each 'my_CountedHandle' object
// acts as a smart pointer, supplying an overloaded 'operator->' that provides
// access to the underlying 'INSTANCE' object via pointer semantics.
//
// 'my_CountedHandle' can also be copied freely; the copy constructor will use
// the 'increment' method from 'my_CountedHandleRep' to note the extra copy.
// Similarly, the destructor will call 'my_CountedHandleRep::decrement' to note
// that there is one fewer handle the underlying 'INSTANCE' has, and delete the
// "rep" object when its reference count is reduced to zero.
//
// Similar to 'my_CountedHandleRep', the class declaration for
// 'my_CountedHandle' is identical to that in 'bsls_atomicoperations':
//..
//                          // ======================
//                          // class my_CountedHandle
//                          // ======================
//
//  template <class INSTANCE>
//  class my_CountedHandle {
//
//      // DATA
//      my_CountedHandleRep<INSTANCE> *d_rep_p;  // shared rep.
//
//    public:
//      // CREATORS
//      my_CountedHandle();
//      my_CountedHandle(INSTANCE        *instance);
//
//      my_CountedHandle(const my_CountedHandle<INSTANCE>& other);
//
//      ~my_CountedHandle();
//
//      // ACCESSORS
//      INSTANCE *operator->() const;
//      int numReferences() const;
//  };
//..
//
///Function Definitions for 'my_CountedHandleRep'
///-  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -
// Next, we provide a definition for the 'static' 'deleteObject' method, which
// is called by the destructor for class 'my_CountedHandle' for the last
// instance of 'my_CountedHandle' using the given "rep" object:
//..
//  template <class INSTANCE>
//  inline
//  void my_CountedHandleRep<INSTANCE>::deleteObject(
//                                       my_CountedHandleRep<INSTANCE> *object)
//  {
//      delete object;
//  }
//..
// Then, we define the constructor for the 'my_CountedHandleRep<INSTANCE>'
// class.  Member 'd_count' is initialized to 1, reflecting the fact that this
// constructor will be called by a new instance of 'my_CountedHandle', which
// instance is our first and only handle when this constructor is called:
// notice that 'd_count' (of type 'bsls::AtomicInt') is initialized as if it
// were a simple integer; its constructor guarantees that the initialization is
// done atomically.
//..
//  template <class INSTANCE>
//  inline
//  my_CountedHandleRep<INSTANCE>:: my_CountedHandleRep(INSTANCE *instance)
//  : d_instance_p(instance)
//  , d_count(1)
//  {
//  }
//..
// Then, we define the destructor, which just deletes 'my_CountedHandle'
// 'd_instance_p':
//..
//  template <class INSTANCE>
//  inline
//  my_CountedHandleRep<INSTANCE>::~my_CountedHandleRep()
//  {
//      delete d_instance_p;
//  }
//..
// Next, we define method 'increment', which is called by 'my_CountedHandle' to
// add a new reference to the current "rep" object, which simply increments
// 'd_count', using the prefix 'operator++':
//..
//  // MANIPULATORS
//  template <class INSTANCE>
//  inline
//  void my_CountedHandleRep<INSTANCE>::increment()
//  {
//      ++d_count;
//  }
//..
// The above operation must be done atomically in a multi-threaded context;
// class 'bsls::AtomicInt' provides this guarantee for all its overloaded
// operators, and 'my_CountedHandleRep' relies upon this guarantee.
//
// Then, we implement method 'decrement', which is called by 'my_CountedHandle'
// when a reference to the current "rep" object is being deleted:
//..
//  template <class INSTANCE>
//  inline
//  int my_CountedHandleRep<INSTANCE>::decrement()
//  {
//      return --d_count;
//  }
//..
// This method atomically decrements the number of references to this
// 'my_CountedHandleRep' and, once again, atomicity is guaranteed by the
// underlying type of 'd_count'.
//
///Function Definitions for 'my_CountedHandle'
///-  -  -  -  -  -  -  -  -  -  -  -  -  -  -
// Next, we define the first constructor for 'my_CountedHandle', which is used
// when creating a handle for a new 'INSTANCE'; note that the 'INSTANCE' is
// constructed separately, and a pointer to that object is passed as the first
// argument ('object'):
//..
//                          // ----------------------
//                          // class my_CountedHandle
//                          // ----------------------
//
//  // CREATORS
//  template <class INSTANCE>
//  inline
//  my_CountedHandle<INSTANCE>::my_CountedHandle(INSTANCE *instance)
//  {
//      d_rep_p = new my_CountedHandleRep<INSTANCE>(instance);
//  }
//..
// Then, we define the copy constructor; the new object copies the underlying
// 'my_CountedHandleRep' and then increments its counter:
//..
//  template <class INSTANCE>
//  inline
//  my_CountedHandle<INSTANCE>::my_CountedHandle(
//                                     const my_CountedHandle<INSTANCE>& other)
//  : d_rep_p(other.d_rep_p)
//  {
//      if (d_rep_p) {
//          d_rep_p->increment();
//      }
//  }
//..
// Next, we define the destructor that decrements the "rep" object's reference
// count using the 'decrement' method.  The 'decrement' method returns the
// object's reference count after the decrement is completed, and
// 'my_CountedHandle' uses this value to determine whether the "rep" object
// should be deleted:
//..
//  template <class INSTANCE>
//  inline
//  my_CountedHandle<INSTANCE>::~my_CountedHandle()
//  {
//      if (d_rep_p && 0 == d_rep_p->decrement()) {
//          my_CountedHandleRep<INSTANCE>::deleteObject(d_rep_p);
//      }
//  }
//..
// Now, we define member 'operator->()', which provides basic pointer semantics
// for 'my_CountedHandle':
//..
//  // ACCESSORS
//  template <class INSTANCE>
//  inline
//  INSTANCE *my_CountedHandle<INSTANCE>::operator->() const
//  {
//      return d_rep_p->d_instance_p;
//  }
//..
// Finally, we define method 'numReferences', which returns the value of the
// reference counter:
//..
//  template <class INSTANCE>
//  inline
//  int my_CountedHandle<INSTANCE>::numReferences() const
//  {
//      return d_rep_p ? d_rep_p->d_count : 0;
//  }
//..
// Note that, while class 'my_CountedHandleRep' is itself fully thread-safe, it
// does not guarantee thread safety for the 'INSTANCE' object.  In order to
// provide thread safety for the 'INSTANCE' in the general case, the "rep"
// would need to use a more general concurrency mechanism such as a mutex.
//
///Example 3: Thread-Safe Lock-Free Singly-Linked List
///- - - - - - - - - - - - - - - - - - - - - - - - - -
// This example demonstrates the use of atomic pointers to implement a fast and
// thread-aware, singly-linked list.  The example class, 'my_PtrStack', is a
// templatized pointer stack, supporting 'push' and 'pop' methods.  The class
// is implemented using a single-linked list.  Nodes in the list are linked
// together using atomic operations.  Instance of this structure are allocated
// using the provided allocator.  When nodes are freed, they are cached on a
// free list.  This free list is also implemented as a single-linked list,
// using atomic pointer operations.
//
// This example parallels the third usage example given for component
// 'bsls_atomicoperations', presenting a different implementation of
// 'my_PtrStack<T>', with an identical public interface.  Note that, where the
// 'bsls_atomicoperations' example uses the basic data type
// 'bsls::AtomicOperations::AtomicTypes::Pointer' for members 'd_list' and
// 'd_freeList', this implementation uses instead the higher-level type
// 'bsls::AtomicPointer<T>'.
//
// First, we create class template, 'my_PtrStack', parameterized by 'TYPE'.
// Instances of this template maintain a list of nodes and a free-node list.
// Each node has a pointer to a data item, 'd_item_p', a link to the next node
// in the list, 'd_next_p' and an atomic flag, 'd_inUseFlag', intended for
// lock-free list manipulation.  The definition of the 'my_PtrStack' class is
// provided below:
//..
//  template <class TYPE>
//  class my_PtrStack {
//      // TYPES
//      struct Node {
//          TYPE                 *d_item_p;
//          Node                 *d_next_p;
//          bsls::AtomicInt       d_inUseFlag; // used to lock this node
//      };
//
//      // DATA
//      bsls::AtomicPointer<Node> d_list;
//      bsls::AtomicPointer<Node> d_freeList;
//
//      // PRIVATE MANIPULATORS
//      Node *allocateNode();
//      void freeNode(Node *node);
//      void deleteNodes(Node *node);
//
//    public:
//      // CREATORS
//      my_PtrStack();
//     ~my_PtrStack();
//
//      // MANIPULATORS
//      void push(TYPE *item);
//      TYPE *pop();
//  };
//..
// Then, we write a constructor that default-initializes the stack.  In the
// corresponding example in 'bsls_atomicoperations', the constructor must also
// initialize the atomic pointer 'd_freeList'.  Since this example uses the
// encapsulated type 'bsls::AtomicPointer', initialization of these member
// variables is done in their default constructors.  Hence, no explicit code is
// required in this constructor:
//..
//  // CREATORS
//  template <class TYPE>
//  inline my_PtrStack<TYPE>::my_PtrStack()
//  {
//  }
//..
// Next, we define the 'deleteNodes' and the destructor function to delete
// nodes that the 'my_PtrStack' object owns.  Note that we don't need to worry
// about the concurrent access to node lists in the destructor, as destructor
// can be executed in only a single thread:
//..
//  template <class TYPE>
//  inline void my_PtrStack<TYPE>::deleteNodes(Node *node)
//  {
//      while (node) {
//          Node *next = node->d_next_p;
//          delete node;
//          node = next;
//      }
//  }
//
//  template <class TYPE>
//  inline my_PtrStack<TYPE>::~my_PtrStack()
//  {
//      deleteNodes(d_list);
//      deleteNodes(d_freeList);
//  }
//..
// Then, we define method 'allocateNode' to get a node from the free list in
// the thread-safe manner by leveraging atomic operations to ensure proper
// thread synchronization:
//..
//  // PRIVATE MANIPULATORS
//  template <class TYPE>
//  typename my_PtrStack<TYPE>::Node *my_PtrStack<TYPE>::allocateNode()
//  {
//      Node *node;
//      while (1) {
//          node = d_freeList; // get the current head
//          if (!node) {
//              break;
//          }
//..
// Next, we try locking the node, and start over if locking fails:
//..
//          if (node->d_inUseFlag.swapInt(1)) {
//              continue;
//          }
//..
// Then, we atomically modify the head if it has not changed.  'testAndSwap'
// compares 'd_freeList' to 'node', replacing 'node' with 'node->d_next_p' only
// if it matches 'd_freeList'.  If 'd_freeList' did not match 'node', then the
// free list has been changed on another thread, between its assignment to the
// 'node' and the call to 'testAndSwap'.  If the list head has changed, then
// try again:
//..
//          if (d_freeList.testAndSwap(node, node->d_next_p) == node) {
//              break;
//          }
//
//          // Unlock the node.
//          node->d_inUseFlag = 0;
//      }
//..
// Next, we allocate a new node if there were no nodes in the free node list:
//..
//      if (!node) {
//          node = new Node();  // should allocate with 'd_allocator_p', but
//                              // here we use 'new' directly for simplicity
//          node->d_inUseFlag = 1;
//      }
//
//      return node;
//  }
//..
// Note that the 'node' is returned in the locked state and remained locked
// until it is added to the free list.
//
// Then, we define the 'freeNode' method to add a given 'node' to the free
// list; 'freeNode' also needs to be synchronized using atomic operations:
//..
//  template <class TYPE>
//  inline void my_PtrStack<TYPE>::freeNode(Node *node)
//  {
//      if (!node) {
//          return;
//      }
//
//      while (1) {
//          node->d_next_p = d_freeList;
//          // Atomically test and swap the head of the list with the
//          // new node.  If the list head has been changed (by another
//          // thread), try again.
//          if (d_freeList.testAndSwap(node->d_next_p, node) == node->d_next_p)
//          {
//              break;
//          }
//      }
//
//      // unlock the 'node'
//      node->d_inUseFlag = 0;
//  }
//..
// Now, we begin to define the public "stack-like" interface for 'my_PtrStack'.
// Note that the 'push' method is similar to 'freeNode', except that it assigns
// an item value and operates on 'd_list', which maintains the list of active
// nodes:
//..
//  // MANIPULATORS
//  template <class TYPE>
//  void my_PtrStack<TYPE>::push(TYPE *item)
//  {
//      Node *node = allocateNode();
//      node->d_item_p = item;
//      while (1) {
//          node->d_next_p = d_list;
//          if (d_list.testAndSwap(node->d_next_p, node) == node->d_next_p) {
//              break;
//          }
//      }
//
//      node->d_inUseFlag = 0;
//  }
//..
// Finally, we define the 'pop' method that removes the node from the top of
// active node list, 'd_list', adds it to the free-node list, and returns the
// data item contained in the node to the caller:
//..
//  template <class TYPE>
//  TYPE *my_PtrStack<TYPE>::pop()
//  {
//      Node *node;
//      while (1) {
//          node = d_list;
//          if (!node) {
//              break;
//          }
//
//          if (node->d_inUseFlag.swapInt(1)) {
//              continue;  // node is locked
//          }
//
//          if (d_list.testAndSwap(node, node->d_next_p) == node) {
//              break;  // node list is being modified in another thread
//          }
//
//          node->d_inUseFlag = 0;
//      }
//
//      TYPE *item = node ? node->d_item_p : 0;
//      if (node) {
//          freeNode(node);
//      }
//      return item;
//  }
//..
// Notice that if the stack was empty, a NULL pointer is returned.

#include <bsls_atomicoperations.h>
#include <bsls_types.h>

namespace BloombergLP {

namespace bsls {

                               // ===============
                               // class AtomicInt
                               // ===============

class AtomicInt {
    // This class implements an atomic integer, which supports common integer
    // operations in a way that is guaranteed to be atomic.  Operations on
    // objects of this class provide the sequential consistency memory ordering
    // guarantee unless explicitly qualified with a less strict consistency
    // guarantee suffix (i.e., Acquire, Release, AcqRel or Relaxed).

    // DATA
    AtomicOperations::AtomicTypes::Int d_value;

  private:
    // NOT IMPLEMENTED
    AtomicInt(const AtomicInt&);               // = delete
    AtomicInt& operator=(const AtomicInt& );   // = delete
        // Note that the copy constructor and the copy-assignment operator are
        // not implemented because they cannot be done atomically.

  public:
    // CREATORS
    AtomicInt();
        // Create an atomic integer object having the default value 0.

    AtomicInt(int value);
        // Create an atomic integer object having the specified 'value'.

    //! ~AtomicInt() = default;
        // Destroy this atomic integer object.

    // MANIPULATORS
    AtomicInt& operator=(int value);
        // Atomically assign the specified 'value' to this object, and return a
        // reference offering modifiable access to 'this' object.

    int operator+=(int value);
        // Atomically add the specified 'value' to this object, and return the
        // resulting value.

    int operator-=(int value);
        // Atomically subtract the specified 'value' from this object, and
        // return the resulting value.

    int operator++();
        // Atomically increment the value of this object by 1 and return the
        // resulting value.

    int operator++(int);
        // Atomically increment the value of this object by 1 and return the
        // value prior to being incremented.

    int operator--();
        // Atomically decrement the value of this object by 1 and return the
        // resulting value.

    int operator--(int);
        // Atomically decrement the value of this object by 1 and return the
        // value prior to being decremented.

    int add(int value);
        // Atomically add the specified 'value' to this object and return the
        // resulting value.

    int addAcqRel(int value);
        // Atomically add the specified 'value' to this object and return the
        // resulting value, providing the acquire/release memory ordering
        // guarantee.

    int addRelaxed(int value);
        // Atomically add the specified 'value' to this object and return the
        // resulting value, providing the relaxed memory ordering guarantee.

    void store(int value);
        // Atomically assign the specified 'value' to this object, providing
        // the sequential consistency memory ordering guarantee.

    void storeRelaxed(int value);
        // Atomically assign the specified 'value' to this object, providing
        // the relaxed memory ordering guarantee.

    void storeRelease(int value);
        // Atomically assign the specified 'value' to this object, providing
        // the release memory ordering guarantee.

    int subtract(int value);
        // Atomically subtract the specified 'value' to this object and return
        // the resulting value.

    int subtractAcqRel(int value);
        // Atomically subtract the specified 'value' to this object and return
        // the resulting value, providing the acquire/release memory ordering
        // guarantee.

    int subtractRelaxed(int value);
        // Atomically subtract the specified 'value' to this object and return
        // the resulting value, providing the relaxed memory ordering
        // guarantee.

    int swap(int swapValue);
        // Atomically set the value of this object to the specified 'swapValue'
        // and return its previous value.

    int swapAcqRel(int swapValue);
        // Atomically set the value of this object to the specified 'swapValue'
        // and return its previous value, providing the acquire/release memory
        // ordering guarantee.

    int testAndSwap(int compareValue, int swapValue);
        // Compare the value of this object to the specified 'compareValue'.
        // If they are equal, set the value of this atomic integer to the
        // specified 'swapValue', otherwise leave this value unchanged.  Return
        // the previous value of this atomic integer, whether or not the swap
        // occurred.  Note that the entire test-and-swap operation is performed
        // atomically.

    int testAndSwapAcqRel(int compareValue, int swapValue);
        // Compare the value of this object to the specified 'compareValue'.
        // If they are equal, set the value of this atomic integer to the
        // specified 'swapValue', otherwise leave this value unchanged.  Return
        // the previous value of this atomic integer, whether or not the swap
        // occurred.  Note that the entire test-and-swap operation is performed
        // atomically and it provides the acquire/release memory ordering
        // guarantee.

    // ACCESSORS
    operator int() const;
        // Return the current value of this object.

    int load() const;
        // Return the current value of this object.

    int loadAcquire() const;
        // Return the current value of this object, providing the acquire
        // memory ordering guarantee.

    int loadRelaxed() const;
        // Return the current value of this object, providing the relaxed
        // memory ordering guarantee.
};

                              // =================
                              // class AtomicInt64
                              // =================

class AtomicInt64 {
    // This class is implements an atomic 64-bit integer, which supports common
    // integer operations in a way that is guaranteed to be atomic.  Operations
    // on objects of this class provide the sequential consistency memory
    // ordering guarantee unless explicitly qualified with a less strict
    // consistency guarantee suffix (i.e., Acquire, Release, AcqRel or
    // Relaxed).

    // DATA
    AtomicOperations::AtomicTypes::Int64 d_value;

  private:
    // NOT IMPLEMENTED
    AtomicInt64(const AtomicInt64&);              // = delete
    AtomicInt64& operator=(const AtomicInt64&);   // = delete
        // Note that the copy constructor and the copy-assignment operator are
        // not implemented because they cannot be done atomically.

  public:
    // CREATORS
    AtomicInt64();
        // Create an atomic 64-bit integer object having the default value 0.

    AtomicInt64(Types::Int64 value);
        // Create an atomic 64-bit integer object having the specified 'value'.

    //! ~AtomicInt64() = default;
        // Destroy this atomic 64-bit integer object.

    // MANIPULATORS
    AtomicInt64& operator=(Types::Int64 value);
        // Atomically assign the specified 'value' to this object, and return a
        // reference offering modifiable access to 'this' object.

    Types::Int64 operator+=(Types::Int64 value);
        // Atomically add the specified 'value' to this object, and return the
        // resulting value.

    Types::Int64 operator-=(Types::Int64 value);
        // Atomically subtract the specified 'value' from this object, and
        // return the resulting value.

    Types::Int64 operator++();
        // Atomically increment the value of this object by 1 and return the
        // resulting value.

    Types::Int64 operator++(int);
        // Atomically increment the value of this object by 1 and return the
        // value prior to being incremented.

    Types::Int64 operator--();
        // Atomically decrement the value of this object by 1 and return the
        // resulting value.

    Types::Int64 operator--(int);
        // Atomically decrement the value of this object by 1 and return the
        // value prior to being decremented.

    Types::Int64 add(Types::Int64 value);
        // Atomically add the specified 'value' to this object and return the
        // resulting value.

    Types::Int64 addAcqRel(Types::Int64 value);
        // Atomically add the specified 'value' to this object and return the
        // resulting value, providing the acquire/release memory ordering
        // guarantee.

    Types::Int64 addRelaxed(Types::Int64 value);
        // Atomically add the specified 'value' to this object and return the
        // resulting value, providing the relaxed memory ordering guarantee.

    void store(Types::Int64 value);
        // Atomically assign the specified 'value' to this object, providing
        // the sequential consistency memory ordering guarantee.

    void storeRelaxed(Types::Int64 value);
        // Atomically assign the specified 'value' to this object, providing
        // the relaxed memory ordering guarantee.

    void storeRelease(Types::Int64 value);
        // Atomically assign the specified 'value' to this object, providing
        // the release memory ordering guarantee.

    Types::Int64 subtract(Types::Int64 value);
        // Atomically subtract the specified 'value' to this object and return
        // the resulting value.

    Types::Int64 subtractAcqRel(Types::Int64 value);
        // Atomically subtract the specified 'value' to this object and return
        // the resulting value, providing the acquire/release memory ordering
        // guarantee.

    Types::Int64 subtractRelaxed(Types::Int64 value);
        // Atomically subtract the specified 'value' to this object and return
        // the resulting value, providing the relaxed memory ordering
        // guarantee.

    Types::Int64 swap(Types::Int64 swapValue);
        // Atomically set the value of this object to the specified 'swapValue'
        // and return its previous value.

    Types::Int64 swapAcqRel(Types::Int64 swapValue);
        // Atomically set the value of this object to the specified 'swapValue'
        // and return its previous value, providing the acquire/release memory
        // ordering guarantee.

    Types::Int64 testAndSwap(Types::Int64 compareValue,
                             Types::Int64 swapValue);
        // Compare the value of this object to the specified 'compareValue'.
        // If they are equal, set the value of this atomic integer to the
        // specified 'swapValue', otherwise leave this value unchanged.  Return
        // the previous value of this atomic integer, whether or not the swap
        // occurred.  Note that the entire test-and-swap operation is performed
        // atomically.

    Types::Int64 testAndSwapAcqRel(Types::Int64 compareValue,
                                   Types::Int64 swapValue);
        // Compare the value of this object to the specified 'compareValue'.
        // If they are equal, set the value of this atomic integer to the
        // specified 'swapValue', otherwise leave this value unchanged.  Return
        // the previous value of this atomic integer, whether or not the swap
        // occurred.  Note that the entire test-and-swap operation is performed
        // atomically and it provides the acquire/release memory ordering
        // guarantee.

    // ACCESSORS
    operator Types::Int64() const;
        // Return the current value of this object.

    Types::Int64 load() const;
        // Return the current value of this object.

    Types::Int64 loadAcquire() const;
        // Return the current value of this object, providing the acquire
        // memory ordering guarantee.

    Types::Int64 loadRelaxed() const;
        // Return the current value of this object, providing the relaxed
        // memory ordering guarantee.
};

                          // ================
                          // class AtomicUint
                          // ================

class AtomicUint {
    // This class implements an atomic unsigned integer, which supports common
    // unsigned integer operations in a way that is guaranteed to be atomic.
    // Operations on objects of this class provide the sequential consistency
    // memory ordering guarantee unless explicitly qualified with a less strict
    // consistency guarantee suffix (i.e., Acquire, Release, AcqRel or
    // Relaxed).

    // DATA
    AtomicOperations::AtomicTypes::Uint d_value;

  private:
    // NOT IMPLEMENTED
    AtomicUint(const AtomicInt&);               // = delete
    AtomicUint& operator=(const AtomicInt& );   // = delete
        // Note that the copy constructor and the copy-assignment operator are
        // not implemented because they cannot be done atomically.

  public:
    // CREATORS
    AtomicUint();
        // Create an atomic unsigned integer object having the default value 0.

    AtomicUint(unsigned int value);
        // Create an atomic unsigned integer object having the specified
        // 'value'.

    //! ~AtomicUint() = default;
        // Destroy this atomic unsigned integer object.

    // MANIPULATORS
    AtomicUint& operator=(unsigned int value);
        // Atomically assign the specified 'value' to this object, and return a
        // reference offering modifiable access to 'this' object.

    unsigned int operator+=(unsigned int value);
        // Atomically add the specified 'value' to this object, and return the
        // resulting value.

    unsigned int operator-=(unsigned int value);
        // Atomically subtract the specified 'value' from this object, and
        // return the resulting value.

    unsigned int operator++();
        // Atomically increment the value of this object by 1 and return the
        // resulting value.

    unsigned int operator++(int);
        // Atomically increment the value of this object by 1 and return the
        // value prior to being incremented.

    unsigned int operator--();
        // Atomically decrement the value of this object by 1 and return the
        // resulting value.

    unsigned int operator--(int);
        // Atomically decrement the value of this object by 1 and return the
        // value prior to being decremented.

    unsigned int add(unsigned int value);
        // Atomically add the specified 'value' to this object and return the
        // resulting value.

    unsigned int addAcqRel(unsigned int value);
        // Atomically add the specified 'value' to this object and return the
        // resulting value, providing the acquire/release memory ordering
        // guarantee.

    unsigned int addRelaxed(unsigned int value);
        // Atomically add the specified 'value' to this object and return the
        // resulting value, providing the relaxed memory ordering guarantee.

    void store(unsigned int value);
        // Atomically assign the specified 'value' to this object, providing
        // the sequential consistency memory ordering guarantee.

    void storeRelaxed(unsigned int value);
        // Atomically assign the specified 'value' to this object, providing
        // the relaxed memory ordering guarantee.

    void storeRelease(unsigned int value);
        // Atomically assign the specified 'value' to this object, providing
        // the release memory ordering guarantee.

    unsigned int subtract(unsigned int value);
        // Atomically subtract the specified 'value' from this object and
        // return the resulting value.

    unsigned int subtractAcqRel(unsigned int value);
        // Atomically subtract the specified 'value' from this object and
        // return the resulting value, providing the acquire/release memory
        // ordering guarantee.

    unsigned int subtractRelaxed(unsigned int value);
        // Atomically subtract the specified 'value' from this object and
        // return the resulting value, providing the relaxed memory ordering
        // guarantee.

    unsigned int swap(unsigned int swapValue);
        // Atomically set the value of this object to the specified 'swapValue'
        // and return its previous value.

    unsigned int swapAcqRel(unsigned int swapValue);
        // Atomically set the value of this object to the specified 'swapValue'
        // and return its previous value, providing the acquire/release memory
        // ordering guarantee.

    unsigned int testAndSwap(unsigned int compareValue,
                             unsigned int swapValue);
        // Compare the value of this object to the specified 'compareValue'.
        // If they are equal, set the value of this atomic unsigned integer to
        // the specified 'swapValue', otherwise leave this value unchanged.
        // Return the previous value of this atomic unsigned integer, whether
        // or not the swap occurred.  Note that the entire test-and-swap
        // operation is performed atomically.

    unsigned int testAndSwapAcqRel(unsigned int compareValue,
                                   unsigned int swapValue);
        // Compare the value of this object to the specified 'compareValue'.
        // If they are equal, set the value of this atomic unsigned integer to
        // the specified 'swapValue', otherwise leave this value unchanged.
        // Return the previous value of this atomic unsigned integer, whether
        // or not the swap occurred.  Note that the entire test-and-swap
        // operation is performed atomically and it provides the
        // acquire/release memory ordering guarantee.

    // ACCESSORS
    operator unsigned int() const;
        // Return the current value of this object.

    unsigned int load() const;
        // Return the current value of this object.

    unsigned int loadAcquire() const;
        // Return the current value of this object, providing the acquire
        // memory ordering guarantee.

    unsigned int loadRelaxed() const;
        // Return the current value of this object, providing the relaxed
        // memory ordering guarantee.
};

                             // ==================
                             // class AtomicUint64
                             // ==================

class AtomicUint64 {
    // This class is implements an atomic 64-bit unsigned integer, which
    // supports common unsigned integer operations in a way that is guaranteed
    // to be atomic.  Operations on objects of this class provide the
    // sequential consistency memory ordering guarantee unless explicitly
    // qualified with a less strict consistency guarantee suffix (i.e.,
    // Acquire, Release, AcqRel or Relaxed).

    // DATA
    AtomicOperations::AtomicTypes::Uint64 d_value;

  private:
    // NOT IMPLEMENTED
    AtomicUint64(const AtomicUint64&);              // = delete
    AtomicUint64& operator=(const AtomicUint64&);   // = delete
        // Note that the copy constructor and the copy-assignment operator are
        // not implemented because they cannot be done atomically.

  public:
    // CREATORS
    AtomicUint64();
        // Create an atomic 64-bit unsigned integer object having the default
        // value 0.

    AtomicUint64(Types::Uint64 value);
        // Create an atomic 64-bit unsigned integer object having the specified
        // 'value'.

    //! ~AtomicUint64() = default;
        // Destroy this atomic 64-bit unsigned integer object.

    // MANIPULATORS
    AtomicUint64& operator=(Types::Uint64 value);
        // Atomically assign the specified 'value' to this object, and return a
        // reference offering modifiable access to 'this' object.

    Types::Uint64 operator+=(Types::Uint64 value);
        // Atomically add the specified 'value' to this object, and return the
        // resulting value.

    Types::Uint64 operator-=(Types::Uint64 value);
        // Atomically subtract the specified 'value' from this object, and
        // return the resulting value.

    Types::Uint64 operator++();
        // Atomically increment the value of this object by 1 and return the
        // resulting value.

    Types::Uint64 operator++(int);
        // Atomically increment the value of this object by 1 and return the
        // value prior to being incremented.

    Types::Uint64 operator--();
        // Atomically decrement the value of this object by 1 and return the
        // resulting value.

    Types::Uint64 operator--(int);
        // Atomically decrement the value of this object by 1 and return the
        // value prior to being decremented.

    Types::Uint64 add(Types::Uint64 value);
        // Atomically add the specified 'value' to this object and return the
        // resulting value.

    Types::Uint64 addRelaxed(Types::Uint64 value);
        // Atomically add the specified 'value' to this object and return the
        // resulting value, providing the relaxed memory ordering guarantee.

    Types::Uint64 addAcqRel(Types::Uint64 value);
        // Atomically add the specified 'value' to this object and return the
        // resulting value, providing the acquire/release memory ordering
        // guarantee.

    void store(Types::Uint64 value);
        // Atomically assign the specified 'value' to this object, providing
        // the sequential consistency memory ordering guarantee.

    void storeRelaxed(Types::Uint64 value);
        // Atomically assign the specified 'value' to this object, providing
        // the relaxed memory ordering guarantee.

    void storeRelease(Types::Uint64 value);
        // Atomically assign the specified 'value' to this object, providing
        // the release memory ordering guarantee.

    Types::Uint64 subtract(Types::Uint64 value);
        // Atomically subtract the specified 'value' from this object and
        // return the resulting value.

    Types::Uint64 subtractAcqRel(Types::Uint64 value);
        // Atomically subtract the specified 'value' from this object and
        // return the resulting value, providing the acquire/release memory
        // ordering guarantee.

    Types::Uint64 subtractRelaxed(Types::Uint64 value);
        // Atomically subtract the specified 'value' from this object and
        // return the resulting value, providing the relaxed memory ordering
        // guarantee.

    Types::Uint64 swap(Types::Uint64 swapValue);
        // Atomically set the value of this object to the specified 'swapValue'
        // and return its previous value.

    Types::Uint64 swapAcqRel(Types::Uint64 swapValue);
        // Atomically set the value of this object to the specified 'swapValue'
        // and return its previous value, providing the acquire/release memory
        // ordering guarantee.

    Types::Uint64 testAndSwap(Types::Uint64 compareValue,
                              Types::Uint64 swapValue);
        // Compare the value of this object to the specified 'compareValue'.
        // If they are equal, set the value of this atomic 64-bit unsigned
        // integer to the specified 'swapValue', otherwise leave this value
        // unchanged.  Return the previous value of this atomic unsigned
        // integer, whether or not the swap occurred.  Note that the entire
        // test-and-swap operation is performed atomically.

    Types::Uint64 testAndSwapAcqRel(Types::Uint64 compareValue,
                                    Types::Uint64 swapValue);
        // Compare the value of this object to the specified 'compareValue'.
        // If they are equal, set the value of this atomic 64-bit unsigned
        // integer to the specified 'swapValue', otherwise leave this value
        // unchanged.  Return the previous value of this atomic unsigned
        // integer, whether or not the swap occurred.  Note that the entire
        // test-and-swap operation is performed atomically and it provides the
        // acquire/release memory ordering guarantee.

    // ACCESSORS
    operator Types::Uint64() const;
        // Return the current value of this object.

    Types::Uint64 load() const;
        // Return the current value of this object.

    Types::Uint64 loadRelaxed() const;
        // Return the current value of this object, providing the relaxed
        // memory ordering guarantee.

    Types::Uint64 loadAcquire() const;
        // Return the current value of this object, providing the acquire
        // memory ordering guarantee.
};

                             // ===================
                             // class AtomicPointer
                             // ===================

template <class TYPE>
class AtomicPointer {
    // This class implements an atomic pointer to a parameterized 'TYPE', which
    // supports common pointer operations in a way that is guaranteed to be
    // atomic.  Operations on objects of this class provide the sequential
    // consistency memory ordering guarantee unless explicitly qualified with a
    // less strict consistency guarantee suffix (i.e., Acquire, Release, AcqRel
    // or Relaxed).

    // PRIVATE TYPES
    typedef char AtomicPointer_PointerSizeCheck[
        sizeof(TYPE *) == sizeof(void *) ? 1 : -1];
        // Static assert that a 'TYPE*' pointer is binary compatible with a
        // 'void*' pointer.  The implementation of 'AtomicPointer' uses
        // 'reinterpret_cast' to convert between 'TYPE*' and 'void*' because
        // function pointers are not implicitly convertible to 'void*', and
        // this assert makes sure that such a cast is safe.  Note that
        // 'bslmf_Assert' can't be used here because of package dependency
        // rules.

    template <class TYPE1>
    struct RemoveConst              { typedef TYPE1 Type; };
    template <class TYPE1>
    struct RemoveConst<TYPE1 const> { typedef TYPE1 Type; };

    typedef typename RemoveConst<TYPE>::Type NcType;

    // DATA
    AtomicOperations::AtomicTypes::Pointer d_value;

  private:
    // NOT IMPLEMENTED
    AtomicPointer(const AtomicPointer<TYPE>&);                  // = delete
    AtomicPointer<TYPE>& operator=(const AtomicPointer<TYPE>&); // = delete
        // Note that the copy constructor and the copy-assignment operator are
        // not implemented because they cannot be done atomically.

  public:
    // CREATORS
    AtomicPointer();
        // Create an atomic pointer object having the default value NULL.

    AtomicPointer(TYPE *value);
        // Create an atomic pointer object having the specified 'value'.

    //! ~AtomicPointer() = default;
        // Destroy this atomic pointer.

    // MANIPULATORS
    AtomicPointer<TYPE>& operator=(TYPE *value);
        // Atomically assign the specified 'value' to this object, and return a
        // reference offering modifiable access to 'this' object.

    void store(TYPE *value);
        // Atomically assign the specified 'value' to this object, providing
        // the sequential consistency memory ordering guarantee.

    void storeRelaxed(TYPE *value);
        // Atomically assign the specified 'value' to this object, providing
        // the relaxed memory ordering guarantee.

    void storeRelease(TYPE *value);
        // Atomically assign the specified 'value' to this object, providing
        // the release memory ordering guarantee.

    TYPE *swap(TYPE *swapValue);
        // Atomically set the value of this object to the specified 'swapValue'
        // and return its previous value.

    TYPE *swapAcqRel(TYPE *swapValue);
        // Atomically set the value of this object to the specified 'swapValue'
        // and return its previous value, providing the acquire/release memory
        // ordering guarantee.

    TYPE *testAndSwap(const TYPE *compareValue, TYPE *swapValue);
        // Compare the value of this object to the specified 'compareValue'.
        // If they are equal, set the value of this atomic pointer to the
        // specified 'swapValue', otherwise leave this value unchanged.  Return
        // the previous value of this atomic pointer, whether or not the swap
        // occurred.  Note that the entire test-and-swap operation is performed
        // atomically.

    TYPE *testAndSwapAcqRel(const TYPE *compareValue, TYPE *swapValue);
        // Compare the value of this object to the specified 'compareValue'.
        // If they are equal, set the value of this atomic pointer to the
        // specified 'swapValue', otherwise leave this value unchanged.  Return
        // the previous value of this atomic pointer, whether or not the swap
        // occurred.  Note that the entire test-and-swap operation is performed
        // atomically and it provides the acquire/release memory ordering
        // guarantee.

    // ACCESSORS
    TYPE& operator*() const;
        // Return a reference to the value currently pointed to by this object.
        // The behavior is undefined if this pointer has a value of 0.

    TYPE *operator->() const;
        // Return the current value of this object.

    operator TYPE*() const;
        // Return the current value of this object.

    TYPE *load() const;
        // Return the current value of this object.

    TYPE *loadRelaxed() const;
        // Return the current value of this object, providing the relaxed
        // memory ordering guarantee.

    TYPE *loadAcquire() const;
        // Return the current value of this object, providing the acquire
        // memory ordering guarantee.
};

                               // ================
                               // class AtomicBool
                               // ================

class AtomicBool {
    // This class implements an atomic boolean, which supports common boolean
    // operations in a way that is guaranteed to be atomic.  Operations on
    // objects of this class provide the sequential consistency memory ordering
    // guarantee unless explicitly qualified with a less strict consistency
    // guarantee suffix (i.e., Acquire, Release, AcqRel or Relaxed).

    // DATA
    enum {
        e_FALSE,
        e_TRUE
    };
    AtomicOperations::AtomicTypes::Int d_value;

  private:
    // NOT IMPLEMENTED
    AtomicBool(const AtomicBool&);               // = delete
    AtomicBool& operator=(const AtomicBool& );   // = delete
        // Note that the copy constructor and the copy-assignment operator are
        // not implemented because they cannot be done atomically.

  public:
    // CREATORS
    AtomicBool();
        // Create an atomic boolean object having the default value 'false'.

    AtomicBool(bool value);
        // Create an atomic boolean object having the specified 'value'.

    //! ~AtomicBool() = default;
        // Destroy this atomic boolean object.

    // MANIPULATORS
    AtomicBool& operator=(bool value);
        // Atomically assign the specified 'value' to this object, and return a
        // reference offering modifiable access to 'this' object.

    void store(bool value);
        // Atomically assign the specified 'value' to this object, providing
        // the sequential consistency memory ordering guarantee.

    void storeRelaxed(bool value);
        // Atomically assign the specified 'value' to this object, providing
        // the relaxed memory ordering guarantee.

    void storeRelease(bool value);
        // Atomically assign the specified 'value' to this object, providing
        // the release memory ordering guarantee.

    bool swap(bool swapValue);
        // Atomically set the value of this object to the specified 'swapValue'
        // and return its previous value.

    bool swapAcqRel(bool swapValue);
        // Atomically set the value of this object to the specified 'swapValue'
        // and return its previous value, providing the acquire/release memory
        // ordering guarantee.

    bool testAndSwap(bool compareValue, bool swapValue);
        // Compare the value of this object to the specified 'compareValue'.
        // If they are equal, set the value of this atomic boolean to the
        // specified 'swapValue', otherwise leave this value unchanged.  Return
        // the previous value of this atomic boolean, whether or not the swap
        // occurred.  Note that the entire test-and-swap operation is performed
        // atomically.

    bool testAndSwapAcqRel(bool compareValue, bool swapValue);
        // Compare the value of this object to the specified 'compareValue'.
        // If they are equal, set the value of this atomic boolean to the
        // specified 'swapValue', otherwise leave this value unchanged.  Return
        // the previous value of this atomic boolean, whether or not the swap
        // occurred.  Note that the entire test-and-swap operation is performed
        // atomically and it provides the acquire/release memory ordering
        // guarantee.

    // ACCESSORS
    operator bool() const;
        // Return the current value of this object.

    bool load() const;
        // Return the current value of this object.

    bool loadRelaxed() const;
        // Return the current value of this object, providing the relaxed
        // memory ordering guarantee.

    bool loadAcquire() const;
        // Return the current value of this object, providing the acquire
        // memory ordering guarantee.
};

}  // close package namespace

namespace bsls {

// ============================================================================
//                        INLINE FUNCTION DEFINITIONS
// ============================================================================

                               // ---------------
                               // class AtomicInt
                               // ---------------

// CREATORS
inline
AtomicInt::AtomicInt()
{
    AtomicOperations_Imp::initInt(&d_value, 0);
}

inline
AtomicInt::AtomicInt(int value)
{
    AtomicOperations_Imp::initInt(&d_value, value);
}

// MANIPULATORS
inline
AtomicInt& AtomicInt::operator=(int value)
{
    AtomicOperations_Imp::setInt(&d_value, value);
    return *this;
}

inline
int AtomicInt::operator+=(int value)
{
    return AtomicOperations_Imp::addIntNv(&d_value, value);
}

inline
int AtomicInt::operator-=(int value)
{
    return AtomicOperations_Imp::subtractIntNv(&d_value, value);
}

inline
int AtomicInt::operator++()
{
    return AtomicOperations_Imp::incrementIntNv(&d_value);
}

inline
int AtomicInt::operator++(int)
{
    return static_cast<int>(
        static_cast<unsigned int>(
            AtomicOperations_Imp::incrementIntNv(&d_value)) - 1);
}

inline
int AtomicInt::operator--()
{
    return AtomicOperations_Imp::decrementIntNv(&d_value);
}

inline
int AtomicInt::operator--(int)
{
    return static_cast<int>(
        static_cast<unsigned int>(
            AtomicOperations_Imp::decrementIntNv(&d_value)) + 1);
}

inline
int AtomicInt::add(int value)
{
    return AtomicOperations_Imp::addIntNv(&d_value, value);
}

inline
int AtomicInt::addAcqRel(int value)
{
    return AtomicOperations_Imp::addIntNvAcqRel(&d_value, value);
}

inline
int AtomicInt::addRelaxed(int value)
{
    return AtomicOperations_Imp::addIntNvRelaxed(&d_value, value);
}

inline
void AtomicInt::store(int value)
{
    AtomicOperations_Imp::setInt(&d_value, value);
}

inline
void AtomicInt::storeRelaxed(int value)
{
    AtomicOperations_Imp::setIntRelaxed(&d_value, value);
}

inline
void AtomicInt::storeRelease(int value)
{
    AtomicOperations_Imp::setIntRelease(&d_value, value);
}

inline
int AtomicInt::subtract(int value)
{
    return AtomicOperations_Imp::subtractIntNv(&d_value, value);
}

inline
int AtomicInt::subtractAcqRel(int value)
{
    return AtomicOperations_Imp::subtractIntNvAcqRel(&d_value, value);
}

inline
int AtomicInt::subtractRelaxed(int value)
{
    return AtomicOperations_Imp::subtractIntNvRelaxed(&d_value, value);
}

inline
int AtomicInt::swap(int swapValue)
{
    return AtomicOperations_Imp::swapInt(&d_value, swapValue);
}

inline
int AtomicInt::swapAcqRel(int swapValue)
{
    return AtomicOperations_Imp::swapIntAcqRel(&d_value, swapValue);
}

inline
int AtomicInt::testAndSwap(int compareValue, int swapValue)
{
    return AtomicOperations_Imp::testAndSwapInt(&d_value,
                                                     compareValue,
                                                     swapValue);
}

inline
int AtomicInt::testAndSwapAcqRel(int compareValue, int swapValue)
{
    return AtomicOperations_Imp::testAndSwapIntAcqRel(&d_value,
                                                      compareValue,
                                                      swapValue);
}

// ACCESSORS

inline
AtomicInt::operator int() const
{
    return AtomicOperations_Imp::getInt(&d_value);
}

inline
int AtomicInt::load() const
{
    return this->operator int();
}

inline
int AtomicInt::loadAcquire() const
{
    return AtomicOperations_Imp::getIntAcquire(&d_value);
}

inline
int AtomicInt::loadRelaxed() const
{
    return AtomicOperations_Imp::getIntRelaxed(&d_value);
}

                              // -----------------
                              // class AtomicInt64
                              // -----------------

// CREATORS
inline
AtomicInt64::AtomicInt64()
{
    AtomicOperations_Imp::initInt64(&d_value, 0);
}

inline
AtomicInt64::AtomicInt64(Types::Int64 value)
{
    AtomicOperations_Imp::initInt64(&d_value, value);
}

// MANIPULATORS
inline
AtomicInt64& AtomicInt64::operator=(Types::Int64 value)
{
    AtomicOperations_Imp::setInt64(&d_value, value);
    return *this;
}

inline
Types::Int64 AtomicInt64::operator+=(Types::Int64 value)
{
    return AtomicOperations_Imp::addInt64Nv(&d_value, value);
}

inline
Types::Int64 AtomicInt64::operator-=(Types::Int64 value)
{
    return AtomicOperations_Imp::subtractInt64Nv(&d_value, value);
}

inline
Types::Int64 AtomicInt64::operator++()
{
    return AtomicOperations_Imp::incrementInt64Nv(&d_value);
}

inline
Types::Int64 AtomicInt64::operator++(int)
{
    return static_cast<Types::Int64>(
        static_cast<Types::Uint64>(
            AtomicOperations_Imp::incrementInt64Nv(&d_value)) - 1);
}

inline
Types::Int64 AtomicInt64::operator--()
{
    return AtomicOperations_Imp::decrementInt64Nv(&d_value);
}

inline
Types::Int64 AtomicInt64::operator--(int)
{
    return static_cast<Types::Int64>(
        static_cast<Types::Uint64>(
            AtomicOperations_Imp::decrementInt64Nv(&d_value)) + 1);
}

inline
Types::Int64 AtomicInt64::add(Types::Int64 value)
{
    return AtomicOperations_Imp::addInt64Nv(&d_value, value);
}

inline
Types::Int64 AtomicInt64::addAcqRel(Types::Int64 value)
{
    return AtomicOperations_Imp::addInt64NvAcqRel(&d_value, value);
}

inline
Types::Int64 AtomicInt64::addRelaxed(Types::Int64 value)
{
    return AtomicOperations_Imp::addInt64NvRelaxed(&d_value, value);
}

inline
void AtomicInt64::store(Types::Int64 value)
{
    AtomicOperations_Imp::setInt64(&d_value, value);
}

inline
void AtomicInt64::storeRelaxed(Types::Int64 value)
{
    AtomicOperations_Imp::setInt64Relaxed(&d_value, value);
}

inline
void AtomicInt64::storeRelease(Types::Int64 value)
{
    AtomicOperations_Imp::setInt64Release(&d_value, value);
}

inline
Types::Int64 AtomicInt64::subtract(Types::Int64 value)
{
    return AtomicOperations_Imp::subtractInt64Nv(&d_value, value);
}

inline
Types::Int64 AtomicInt64::subtractAcqRel(Types::Int64 value)
{
    return AtomicOperations_Imp::subtractInt64NvAcqRel(&d_value, value);
}

inline
Types::Int64 AtomicInt64::subtractRelaxed(Types::Int64 value)
{
    return AtomicOperations_Imp::subtractInt64NvRelaxed(&d_value, value);
}

inline
Types::Int64 AtomicInt64::swap(Types::Int64 swapValue)
{
    return AtomicOperations_Imp::swapInt64(&d_value, swapValue);
}

inline
Types::Int64 AtomicInt64::swapAcqRel(Types::Int64 swapValue)
{
    return AtomicOperations_Imp::swapInt64AcqRel(&d_value, swapValue);
}

inline
Types::Int64
AtomicInt64::testAndSwap(Types::Int64 compareValue,
                         Types::Int64 swapValue)
{
    return AtomicOperations_Imp::testAndSwapInt64(&d_value,
                                                       compareValue,
                                                       swapValue);
}

inline
Types::Int64
AtomicInt64::testAndSwapAcqRel(Types::Int64 compareValue,
                               Types::Int64 swapValue)
{
    return AtomicOperations_Imp::testAndSwapInt64AcqRel(&d_value,
                                                        compareValue,
                                                        swapValue);
}

// ACCESSORS
inline
AtomicInt64::operator Types::Int64() const
{
    return AtomicOperations_Imp::getInt64(&d_value);
}

inline
Types::Int64 AtomicInt64::load() const
{
    return this->operator Types::Int64();
}

inline
Types::Int64 AtomicInt64::loadAcquire() const
{
    return AtomicOperations_Imp::getInt64Acquire(&d_value);
}

inline
Types::Int64 AtomicInt64::loadRelaxed() const
{
    return AtomicOperations_Imp::getInt64Relaxed(&d_value);
}

                              // ---------------
                              // class AtomicUint
                              // ---------------

// CREATORS
inline
AtomicUint::AtomicUint()
{
    AtomicOperations_Imp::initUint(&d_value, 0);
}

inline
AtomicUint::AtomicUint(unsigned int value)
{
    AtomicOperations_Imp::initUint(&d_value, value);
}

// MANIPULATORS
inline
AtomicUint& AtomicUint::operator=(unsigned int value)
{
    AtomicOperations_Imp::setUint(&d_value, value);
    return *this;
}

inline
unsigned int AtomicUint::operator+=(unsigned int value)
{
    return AtomicOperations_Imp::addUintNv(&d_value, value);
}

inline
unsigned int AtomicUint::operator-=(unsigned int value)
{
    return AtomicOperations_Imp::subtractUintNv(&d_value, value);
}

inline
unsigned int AtomicUint::operator++()
{
    return AtomicOperations_Imp::incrementUintNv(&d_value);
}

inline
unsigned int AtomicUint::operator++(int)
{
    return AtomicOperations_Imp::incrementUintNv(&d_value) - 1;
}

inline
unsigned int AtomicUint::operator--()
{
    return AtomicOperations_Imp::decrementUintNv(&d_value);
}

inline
unsigned int AtomicUint::operator--(int)
{
    return AtomicOperations_Imp::decrementUintNv(&d_value) + 1;
}

inline
unsigned int AtomicUint::add(unsigned int value)
{
    return AtomicOperations_Imp::addUintNv(&d_value, value);
}

inline
unsigned int AtomicUint::addAcqRel(unsigned int value)
{
    return AtomicOperations_Imp::addUintNvAcqRel(&d_value, value);
}

inline
unsigned int AtomicUint::addRelaxed(unsigned int value)
{
    return AtomicOperations_Imp::addUintNvRelaxed(&d_value, value);
}

inline
void AtomicUint::store(unsigned int value)
{
    AtomicOperations_Imp::setUint(&d_value, value);
}

inline
void AtomicUint::storeRelaxed(unsigned int value)
{
    AtomicOperations_Imp::setUintRelaxed(&d_value, value);
}

inline
void AtomicUint::storeRelease(unsigned int value)
{
    AtomicOperations_Imp::setUintRelease(&d_value, value);
}

inline
unsigned int AtomicUint::subtract(unsigned int value)
{
    return AtomicOperations_Imp::subtractUintNv(&d_value, value);
}

inline
unsigned int AtomicUint::subtractAcqRel(unsigned int value)
{
    return AtomicOperations_Imp::subtractUintNvAcqRel(&d_value, value);
}

inline
unsigned int AtomicUint::subtractRelaxed(unsigned int value)
{
    return AtomicOperations_Imp::subtractUintNvRelaxed(&d_value, value);
}

inline
unsigned int AtomicUint::swap(unsigned int swapValue)
{
    return AtomicOperations_Imp::swapUint(&d_value, swapValue);
}

inline
unsigned int AtomicUint::swapAcqRel(unsigned int swapValue)
{
    return AtomicOperations_Imp::swapUintAcqRel(&d_value, swapValue);
}

inline
unsigned int AtomicUint::testAndSwap(unsigned int compareValue,
                                     unsigned int swapValue)
{
    return AtomicOperations_Imp::testAndSwapUint(&d_value,
                                                  compareValue,
                                                  swapValue);
}

inline
unsigned int AtomicUint::testAndSwapAcqRel(unsigned int compareValue,
                                           unsigned int swapValue)
{
    return AtomicOperations_Imp::testAndSwapUintAcqRel(&d_value,
                                                        compareValue,
                                                        swapValue);
}

// ACCESSORS

inline
AtomicUint::operator unsigned int() const
{
    return AtomicOperations_Imp::getUint(&d_value);
}

inline
unsigned int AtomicUint::load() const
{
    return this->operator unsigned int();
}

inline
unsigned int AtomicUint::loadAcquire() const
{
    return AtomicOperations_Imp::getUintAcquire(&d_value);
}

inline
unsigned int AtomicUint::loadRelaxed() const
{
    return AtomicOperations_Imp::getUintRelaxed(&d_value);
}

                              // -----------------
                              // class AtomicUint64
                              // -----------------

// CREATORS
inline
AtomicUint64::AtomicUint64()
{
    AtomicOperations_Imp::initUint64(&d_value, 0);
}

inline
AtomicUint64::AtomicUint64(Types::Uint64 value)
{
    AtomicOperations_Imp::initUint64(&d_value, value);
}

// MANIPULATORS
inline
AtomicUint64& AtomicUint64::operator=(Types::Uint64 value)
{
    AtomicOperations_Imp::setUint64(&d_value, value);
    return *this;
}

inline
Types::Uint64 AtomicUint64::operator+=(Types::Uint64 value)
{
    return AtomicOperations_Imp::addUint64Nv(&d_value, value);
}

inline
Types::Uint64 AtomicUint64::operator-=(Types::Uint64 value)
{
    return AtomicOperations_Imp::subtractUint64Nv(&d_value, value);
}

inline
Types::Uint64 AtomicUint64::operator++()
{
    return AtomicOperations_Imp::incrementUint64Nv(&d_value);
}

inline
Types::Uint64 AtomicUint64::operator++(int)
{
    return AtomicOperations_Imp::incrementUint64Nv(&d_value) - 1;
}

inline
Types::Uint64 AtomicUint64::operator--()
{
    return AtomicOperations_Imp::decrementUint64Nv(&d_value);
}

inline
Types::Uint64 AtomicUint64::operator--(int)
{
    return AtomicOperations_Imp::decrementUint64Nv(&d_value) + 1;
}

inline
Types::Uint64 AtomicUint64::add(Types::Uint64 value)
{
    return AtomicOperations_Imp::addUint64Nv(&d_value, value);
}

inline
Types::Uint64 AtomicUint64::addAcqRel(Types::Uint64 value)
{
    return AtomicOperations_Imp::addUint64NvAcqRel(&d_value, value);
}

inline
Types::Uint64 AtomicUint64::addRelaxed(Types::Uint64 value)
{
    return AtomicOperations_Imp::addUint64NvRelaxed(&d_value, value);
}

inline
void AtomicUint64::store(Types::Uint64 value)
{
    AtomicOperations_Imp::setUint64(&d_value, value);
}

inline
void AtomicUint64::storeRelaxed(Types::Uint64 value)
{
    AtomicOperations_Imp::setUint64Relaxed(&d_value, value);
}

inline
void AtomicUint64::storeRelease(Types::Uint64 value)
{
    AtomicOperations_Imp::setUint64Release(&d_value, value);
}

inline
Types::Uint64 AtomicUint64::subtract(Types::Uint64 value)
{
    return AtomicOperations_Imp::subtractUint64Nv(&d_value, value);
}

inline
Types::Uint64 AtomicUint64::subtractAcqRel(Types::Uint64 value)
{
    return AtomicOperations_Imp::subtractUint64NvAcqRel(&d_value, value);
}

inline
Types::Uint64 AtomicUint64::subtractRelaxed(Types::Uint64 value)
{
    return AtomicOperations_Imp::subtractUint64NvRelaxed(&d_value, value);
}

inline
Types::Uint64 AtomicUint64::swap(Types::Uint64 swapValue)
{
    return AtomicOperations_Imp::swapUint64(&d_value, swapValue);
}

inline
Types::Uint64 AtomicUint64::swapAcqRel(Types::Uint64 swapValue)
{
    return AtomicOperations_Imp::swapUint64AcqRel(&d_value, swapValue);
}

inline
Types::Uint64 AtomicUint64::testAndSwap(Types::Uint64 compareValue,
                                        Types::Uint64 swapValue)
{
    return AtomicOperations_Imp::testAndSwapUint64(&d_value,
                                                    compareValue,
                                                    swapValue);
}

inline
Types::Uint64 AtomicUint64::testAndSwapAcqRel(Types::Uint64 compareValue,
                                              Types::Uint64 swapValue)
{
    return AtomicOperations_Imp::testAndSwapUint64AcqRel(&d_value,
                                                          compareValue,
                                                          swapValue);
}

// ACCESSORS
inline
AtomicUint64::operator Types::Uint64() const
{
    return AtomicOperations_Imp::getUint64(&d_value);
}

inline
Types::Uint64 AtomicUint64::load() const
{
    return this->operator Types::Uint64();
}

inline
Types::Uint64 AtomicUint64::loadAcquire() const
{
    return AtomicOperations_Imp::getUint64Acquire(&d_value);
}

inline
Types::Uint64 AtomicUint64::loadRelaxed() const
{
    return AtomicOperations_Imp::getUint64Relaxed(&d_value);
}

                             // -------------------
                             // class AtomicPointer
                             // -------------------

// CREATORS
template <class TYPE>
inline
AtomicPointer<TYPE>::AtomicPointer()
{
    AtomicOperations_Imp::initPointer(&d_value, 0);
}

template <class TYPE>
inline
AtomicPointer<TYPE>::AtomicPointer(TYPE *value)
{
    AtomicOperations_Imp::initPointer(
            &d_value,
            reinterpret_cast<void *>(const_cast<NcType *>(value)));
}

// MANIPULATORS
template <class TYPE>
inline
AtomicPointer<TYPE>&
AtomicPointer<TYPE>::operator=(TYPE *value)
{
    AtomicOperations_Imp::setPtr(
            &d_value,
            reinterpret_cast<void *>(const_cast<NcType *>(value)));
    return *this;
}

template <class TYPE>
inline
void AtomicPointer<TYPE>::store(TYPE *value)
{
    AtomicOperations_Imp::setPtr(
            &d_value,
            reinterpret_cast<void *>(const_cast<NcType *>(value)));
}

template <class TYPE>
inline
void AtomicPointer<TYPE>::storeRelaxed(TYPE *value)
{
    AtomicOperations_Imp::setPtrRelaxed(
            &d_value,
            reinterpret_cast<void *>(const_cast<NcType *>(value)));
}

template <class TYPE>
inline
void AtomicPointer<TYPE>::storeRelease(TYPE *value)
{
    AtomicOperations_Imp::setPtrRelease(
            &d_value,
            reinterpret_cast<void *>(const_cast<NcType *>(value)));
}

template <class TYPE>
inline
TYPE *AtomicPointer<TYPE>::swap(TYPE *swapValue)
{
    return reinterpret_cast<TYPE *>(
        AtomicOperations_Imp::swapPtr(
            &d_value,
            reinterpret_cast<void *>(const_cast<NcType *>(swapValue))));
}

template <class TYPE>
inline
TYPE *AtomicPointer<TYPE>::swapAcqRel(TYPE *swapValue)
{
    return reinterpret_cast<TYPE *>(
        AtomicOperations_Imp::swapPtrAcqRel(
            &d_value,
            reinterpret_cast<void *>(const_cast<NcType *>(swapValue))));
}

template <class TYPE>
inline
TYPE *AtomicPointer<TYPE>::testAndSwap(const TYPE *compareValue,
                                       TYPE       *swapValue)
{
    return reinterpret_cast<TYPE *>(
        AtomicOperations_Imp::testAndSwapPtr(
            &d_value,
            reinterpret_cast<void *>(const_cast<NcType *>(compareValue)),
            reinterpret_cast<void *>(const_cast<NcType *>(swapValue))));
}

template <class TYPE>
inline
TYPE *AtomicPointer<TYPE>::testAndSwapAcqRel(const TYPE *compareValue,
                                             TYPE       *swapValue)
{
    return reinterpret_cast<TYPE *>(
        AtomicOperations_Imp::testAndSwapPtrAcqRel(
            &d_value,
            reinterpret_cast<void *>(const_cast<NcType *>(compareValue)),
            reinterpret_cast<void *>(const_cast<NcType *>(swapValue))));
}

// ACCESSORS
template <class TYPE>
inline
AtomicPointer<TYPE>::operator TYPE*() const
{
    return static_cast<TYPE *>(AtomicOperations_Imp::getPtr(&d_value));
}

template <class TYPE>
inline
TYPE& AtomicPointer<TYPE>::operator*() const
{
    return *(static_cast<TYPE *>(AtomicOperations_Imp::getPtr(&d_value)));
}

template <class TYPE>
inline
TYPE *AtomicPointer<TYPE>::operator->() const
{
    return static_cast<TYPE *>(AtomicOperations_Imp::getPtr(&d_value));
}

template <class TYPE>
inline
TYPE *AtomicPointer<TYPE>::load() const
{
    return this->operator TYPE*();
}

template <class TYPE>
inline
TYPE *AtomicPointer<TYPE>::loadAcquire() const
{
    return static_cast<TYPE *>(AtomicOperations_Imp::getPtrAcquire(&d_value));
}

template <class TYPE>
inline
TYPE *AtomicPointer<TYPE>::loadRelaxed() const
{
    return static_cast<TYPE *>(AtomicOperations_Imp::getPtrRelaxed(&d_value));
}

                               // ----------------
                               // class AtomicBool
                               // ----------------

// CREATORS
inline
AtomicBool::AtomicBool()
{
    AtomicOperations_Imp::initInt(&d_value, AtomicBool::e_FALSE);
}

inline
AtomicBool::AtomicBool(bool value)
{
    AtomicOperations_Imp::initInt(
        &d_value,
        value ? AtomicBool::e_TRUE : AtomicBool::e_FALSE);
}

// MANIPULATORS
inline
AtomicBool& AtomicBool::operator=(bool value)
{
    AtomicOperations_Imp::setInt(
        &d_value,
        value ? AtomicBool::e_TRUE : AtomicBool::e_FALSE);
    return *this;
}

inline
void AtomicBool::store(bool value)
{
    AtomicOperations_Imp::setInt(
        &d_value,
        value ? AtomicBool::e_TRUE : AtomicBool::e_FALSE);
}

inline
void AtomicBool::storeRelaxed(bool value)
{
    AtomicOperations_Imp::setIntRelaxed(
        &d_value,
        value ? AtomicBool::e_TRUE : AtomicBool::e_FALSE);
}

inline
void AtomicBool::storeRelease(bool value)
{
    AtomicOperations_Imp::setIntRelease(
        &d_value,
        value ? AtomicBool::e_TRUE : AtomicBool::e_FALSE);
}

inline
bool AtomicBool::swap(bool swapValue)
{
    return AtomicOperations_Imp::swapInt(
            &d_value,
            swapValue ? AtomicBool::e_TRUE : AtomicBool::e_FALSE)
        == AtomicBool::e_TRUE;
}

inline
bool AtomicBool::swapAcqRel(bool swapValue)
{
    return AtomicOperations_Imp::swapIntAcqRel(
            &d_value,
            swapValue ? AtomicBool::e_TRUE : AtomicBool::e_FALSE)
        == AtomicBool::e_TRUE;
}

inline
bool AtomicBool::testAndSwap(bool compareValue, bool swapValue)
{
    return AtomicOperations_Imp::testAndSwapInt(
            &d_value,
            compareValue ? AtomicBool::e_TRUE : AtomicBool::e_FALSE,
            swapValue ? AtomicBool::e_TRUE : AtomicBool::e_FALSE)
        == AtomicBool::e_TRUE;
}

inline
bool AtomicBool::testAndSwapAcqRel(bool compareValue, bool swapValue)
{
    return AtomicOperations_Imp::testAndSwapIntAcqRel(
            &d_value,
            compareValue ? AtomicBool::e_TRUE : AtomicBool::e_FALSE,
            swapValue ? AtomicBool::e_TRUE : AtomicBool::e_FALSE)
        == AtomicBool::e_TRUE;
}

// ACCESSORS

inline
AtomicBool::operator bool() const
{
    return AtomicOperations_Imp::getInt(&d_value) == AtomicBool::e_TRUE;
}

inline
bool AtomicBool::load() const
{
    return this->operator bool();
}

inline
bool AtomicBool::loadAcquire() const
{
    return AtomicOperations_Imp::getIntAcquire(&d_value) == AtomicBool::e_TRUE;
}

inline
bool AtomicBool::loadRelaxed() const
{
    return AtomicOperations_Imp::getIntRelaxed(&d_value) == AtomicBool::e_TRUE;
}

}  // close package namespace

}  // close enterprise namespace

#endif

// ----------------------------------------------------------------------------
// Copyright 2013 Bloomberg Finance L.P.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ----------------------------- END-OF-FILE ----------------------------------