
//  Copyright <2022> <Hans de Nivelle>
//
//  This software is released with the 3-clause BSD license, which 
//  is given below: 
// 
//  Redistribution and use in source and binary forms, with or without 
//  modification, are permitted provided that the following conditions are met:

//  Redistributions of source code must retain the above copyright notice, 
//  this list of conditions and the following disclaimer:

//  Redistributions in binary form must reproduce the above copyright notice, 
//  this list of conditions and the following disclaimer in the documentation 
//  and/or other materials provided with the distribution.
//  Neither the name of the copyright holder nor the names of its contributors 
//  may be used to endorse or promote products derived from this software 
//  without specific prior written permission.

//  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 COPYRIGHT 
//  HOLDER OR CONTRIBUTORS 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.



// Written by Dina Muktubayeva, April 2021.

#include "stateset.h"

// This hash function need not be commutative, because
// state sets are ordered.

size_t lexing::stateset::hash::operator( )( const stateset& set ) const 
{
   size_t h = 0;
   for( auto s : set )
   {
      h ^= h << 13;
      h ^= h >> 7;
      h ^= h << 17;
      h ^= s. nr;
   }
   return h;
}


bool lexing::stateset::equal_to::operator( )(
         const stateset& s1, const stateset& s2 ) const
{
   if( s1.size() != s2.size() )
      return false;

   auto it1 = s1.begin();
   auto it2 = s2.begin();

   while( it1 != s1. end( ))
   {
      if( *it1 != *it2 )
         return false;

      ++ it1;
      ++ it2;
   }

   return true;
}


void lexing::stateset::print( std::ostream& out ) const 
{
   out << "{";
   for( auto st = states.begin(); st != states.end(); ++ st )
   {
      if( st != states.begin())
         out << ", ";
      else
         out << " ";

      out << *st;
   }
   out << " }";
}



