text: /**
  * @file types.hpp
  * @brief Header of all the types.
  *
  * @section LICENSE
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR/AUTHORS BE LIABLE FOR ANY
  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *
  * @original author 
  * @bug No known bugs.
  * @version 0.1.0.0
  *
  // Copyright (C) 2005  Davis E. King (davis@dlib.net)
  // License: Boost Software License   See LICENSE.txt for the full license.
  */
  
  #ifndef CMNIP_CMNIPCORE_UINT_HPP__
  #define CMNIP_CMNIPCORE_UINT_HPP__
  
  
  #include "assert.hpp"
  
  namespace CmnIP
  {
  namespace core
  {
  
  /*!
      uint64 is a typedef for an unsigned integer that is exactly 64 bits wide.
      uint32 is a typedef for an unsigned integer that is exactly 32 bits wide.
      uint16 is a typedef for an unsigned integer that is exactly 16 bits wide.
      uint8  is a typedef for an unsigned integer that is exactly 8  bits wide.
  
      int64 is a typedef for an integer that is exactly 64 bits wide.
      int32 is a typedef for an integer that is exactly 32 bits wide.
      int16 is a typedef for an integer that is exactly 16 bits wide.
      int8  is a typedef for an integer that is exactly 8  bits wide.
  !*/
  
  
  #ifdef __GNUC__
  typedef unsigned long long uint64;
  typedef long long int64;
  #elif defined(__BORLANDC__)
  typedef unsigned __int64 uint64;
  typedef __int64 int64;
  #elif defined(_MSC_VER)
  typedef unsigned __int64 uint64;
  typedef __int64 int64;
  #else
  typedef unsigned long long uint64;
  typedef long long int64;
  #endif
  
  typedef unsigned short uint16;
  typedef unsigned int   uint32;
  typedef unsigned char  uint8;
  
  typedef short int16;
  typedef int   int32;
  typedef char  int8;
  
  
  // make sure these types have the right sizes on this platform
  COMPILE_TIME_ASSERT(sizeof(uint8)  == 1);
  COMPILE_TIME_ASSERT(sizeof(uint16) == 2);
  COMPILE_TIME_ASSERT(sizeof(uint32) == 4);
  COMPILE_TIME_ASSERT(sizeof(uint64) == 8);
  
  COMPILE_TIME_ASSERT(sizeof(int8)  == 1);
  COMPILE_TIME_ASSERT(sizeof(int16) == 2);
  COMPILE_TIME_ASSERT(sizeof(int32) == 4);
  COMPILE_TIME_ASSERT(sizeof(int64) == 8);
  
  
  
  template <typename T, size_t s = sizeof(T)>
  struct unsigned_type;
  template <typename T>
  struct unsigned_type<T,1> { typedef uint8 type; };
  template <typename T>
  struct unsigned_type<T,2> { typedef uint16 type; };
  template <typename T>
  struct unsigned_type<T,4> { typedef uint32 type; };
  template <typename T>
  struct unsigned_type<T,8> { typedef uint64 type; };
  /*!
      ensures
          - sizeof(unsigned_type<T>::type) == sizeof(T)
          - unsigned_type<T>::type is an unsigned integral type
  !*/
  
  template <typename T, typename U>
  T zero_extend_cast(
      const U val
  )
  /*!
      requires
          - U and T are integral types
      ensures
          - let ut be a typedef for unsigned_type<U>::type
          - return static_cast<T>(static_cast<ut>(val));
  !*/
  {
      typedef typename unsigned_type<U>::type ut;
      return static_cast<T>(static_cast<ut>(val));
  }
  
  } // namespace core
  } // namespace CmnIP
  
  
  #endif /* CMNIP_CORE_TYPES_HPP__ */
  