text: /*
   *                   GridGain Community Edition Licensing
   *                   Copyright 2019 GridGain Systems, Inc.
   *
   * Licensed under the Apache License, Version 2.0 (the "License") modified with Commons Clause
   * Restriction; 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.
   *
   * Commons Clause Restriction
   *
   * The Software is provided to you by the Licensor under the License, as defined below, subject to
   * the following condition.
   *
   * Without limiting other conditions in the License, the grant of rights under the License will not
   * include, and the License does not grant to you, the right to Sell the Software.
   * For purposes of the foregoing, “Sell” means practicing any or all of the rights granted to you
   * under the License to provide to third parties, for a fee or other consideration (including without
   * limitation fees for hosting or consulting/ support services related to the Software), a product or
   * service whose value derives, entirely or substantially, from the functionality of the Software.
   * Any license notice or attribution required by the License must also include this Commons Clause
   * License Condition notice.
   *
   * For purposes of the clause above, the “Licensor” is Copyright 2019 GridGain Systems, Inc.,
   * the “License” is the Apache License, Version 2.0, and the Software is the GridGain Community
   * Edition software provided with this notice.
   */
  
  /**
   * @file
   * Declares ignite::Guid class.
   */
  
  #ifndef _IGNITE_GUID
  #define _IGNITE_GUID
  
  #include <stdint.h>
  #include <iomanip>
  
  #include <ignite/common/common.h>
  
  namespace ignite
  {
      /**
       * Global universally unique identifier (GUID).
       */
      class IGNITE_IMPORT_EXPORT Guid
      {
      public:
          /**
           * Default constructor.
           */
          Guid();
  
          /**
           * Constructor.
           *
           * @param most Most significant bits.
           * @param least Least significant bits.
           */
          Guid(int64_t most, int64_t least);
  
          /**
           * Returns the most significant 64 bits of this instance.
           *
           * @return The most significant 64 bits of this instance.
           */
          int64_t GetMostSignificantBits() const;
  
          /**
           * Returns the least significant 64 bits of this instance.
           *  
           * @return The least significant 64 bits of this instance.
           */
          int64_t GetLeastSignificantBits() const;
  
          /**
           * The version number associated with this instance.  The version
           * number describes how this Guid was generated.
           *
           * The version number has the following meaning:
           * 1    Time-based UUID;
           * 2    DCE security UUID;
           * 3    Name-based UUID;
           * 4    Randomly generated UUID.
           *
           * @return The version number of this instance.
           */
          int32_t GetVersion() const;
  
          /**
           * The variant number associated with this instance. The variant
           * number describes the layout of the Guid.
           *
           * The variant number has the following meaning:
           * 0    Reserved for NCS backward compatibility;
           * 2    IETF RFC 4122 (Leach-Salz), used by this class;
           * 6    Reserved, Microsoft Corporation backward compatibility;
           * 7    Reserved for future definition.
           *
           * @return The variant number of this instance.
           */
          int32_t GetVariant() const;
  
          /**
           * Get hash code of this instance (used in serialization).
           *
           * @return Hash code.
           */
          int32_t GetHashCode() const;
  
          /**
           * Comparison operator override.
           *
           * @param val1 First value.
           * @param val2 Second value.
           * @return True if equal.
           */
          friend bool IGNITE_IMPORT_EXPORT operator== (const Guid& val1, const Guid& val2);
      private:
          /** Most significant bits. */
          int64_t most;  
  
          /** Least significant bits. */
          int64_t least; 
      };
  
      /**
       * Output operator.
       *
       * @param os Output stream.
       * @param guid Guid to output.
       * @return Reference to the first param.
       */
      template<typename C>
      ::std::basic_ostream<C>& operator<<(std::basic_ostream<C>& os, const Guid& guid)
      {
          uint32_t part1 = static_cast<uint32_t>(guid.GetMostSignificantBits() >> 32);
          uint16_t part2 = static_cast<uint16_t>(guid.GetMostSignificantBits() >> 16);
          uint16_t part3 = static_cast<uint16_t>(guid.GetMostSignificantBits());
          uint16_t part4 = static_cast<uint16_t>(guid.GetLeastSignificantBits() >> 48);
          uint64_t part5 = guid.GetLeastSignificantBits() & 0x0000FFFFFFFFFFFFULL;
  
          os  << std::setfill<C>('0') << std::setw(8)  << std::hex << part1 << '-'
              << std::setfill<C>('0') << std::setw(4)  << std::hex << part2 << '-'
              << std::setfill<C>('0') << std::setw(4)  << std::hex << part3 << '-'
              << std::setfill<C>('0') << std::setw(4)  << std::hex << part4 << '-'
              << std::setfill<C>('0') << std::setw(12) << std::hex << part5;
  
          return os;
      }
  
      /**
       * Input operator.
       *
       * @param is Input stream.
       * @param guid Guid to input.
       * @return Reference to the first param.
       */
      template<typename C>
      ::std::basic_istream<C>& operator>>(std::basic_istream<C>& is, Guid& guid)
      {
          uint64_t parts[5];
  
          C delim;
  
          for (int i = 0; i < 4; ++i)
          {
              is >> std::hex >> parts[i] >> delim;
  
              if (delim != static_cast<C>('-'))
                  return is;
          }
  
          is >> std::hex >> parts[4];
  
          guid = Guid((parts[0] << 32) | (parts[1] << 16) | parts[2], (parts[3] << 48) | parts[4]);
  
          return is;
      }
  }
  
  #endif