@ -920,6 +920,12 @@ template<int S, int H> class HashObject; // for Google's benchmark, not in spp n 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    # define SPP_NOEXCEPT noexcept  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					# endif  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					# ifdef SPP_NO_CXX11_CONSTEXPR  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    # define SPP_CONSTEXPR  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					# else  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    # define SPP_CONSTEXPR constexpr  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					# endif  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					# define SPP_INLINE  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					# ifndef SPP_NAMESPACE  
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				
					@ -955,75 +961,109 @@ struct spp_hash<T *> 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    SPP_INLINE  size_t  operator ( ) ( const  T  * __v )  const  SPP_NOEXCEPT   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        static  const  size_t  shift  =  spp_log2 ( 1  +  sizeof ( T ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        static  const  size_t  shift  =  3 ;  / /  spp_log2 ( 1  +  sizeof ( T ) ) ;  / /  T  might  be  incomplete !   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        return  static_cast < size_t > ( ( * ( reinterpret_cast < const  uintptr_t  * > ( & __v ) ) )  > >  shift ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					} ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					/ /  from  http : / / burtleburtle . net / bob / hash / integer . html  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					/ /  fast  and  efficient  for  power  of  two  table  sizes  where  we  always   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					/ /  consider  the  last  bits .  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					/ /  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					inline  size_t  spp_mix_32 ( uint32_t  a )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					{  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    a  =  a  ^  ( a  > >  4 ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    a  =  ( a  ^  0xdeadbeef )  +  ( a  < <  5 ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    a  =  a  ^  ( a  > >  11 ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    return  static_cast < size_t > ( a ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					}  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					/ /  Maybe  we  should  do  a  more  thorough  scrambling  as  described  in   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					/ /  https : / / gist . github . com / badboy / 6267743  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					/ /  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					inline  size_t  spp_mix_64 ( uint64_t  a )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					{  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    a  =  a  ^  ( a  > >  4 ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    a  =  ( a  ^  0xdeadbeef )  +  ( a  < <  5 ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    a  =  a  ^  ( a  > >  11 ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    return  a ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					}  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					template  < >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					struct  spp_hash < bool >  :  public  std : : unary_function < bool ,  size_t >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					{  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    SPP_INLINE  size_t  operator ( ) ( bool  __v )  const  SPP_NOEXCEPT  { return  static_cast < size_t > ( __v ) ; }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    SPP_INLINE  size_t  operator ( ) ( bool  __v )  const  SPP_NOEXCEPT   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    {  return  static_cast < size_t > ( __v ) ;  }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					} ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					template  < >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					struct  spp_hash < char >  :  public  std : : unary_function < char ,  size_t >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					{  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    SPP_INLINE  size_t  operator ( ) ( char  __v )  const  SPP_NOEXCEPT  { return  static_cast < size_t > ( __v ) ; }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    SPP_INLINE  size_t  operator ( ) ( char  __v )  const  SPP_NOEXCEPT   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    {  return  static_cast < size_t > ( __v ) ;  }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					} ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					template  < >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					struct  spp_hash < signed  char >  :  public  std : : unary_function < signed  char ,  size_t >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					{  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    SPP_INLINE  size_t  operator ( ) ( signed  char  __v )  const  SPP_NOEXCEPT  { return  static_cast < size_t > ( __v ) ; }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    SPP_INLINE  size_t  operator ( ) ( signed  char  __v )  const  SPP_NOEXCEPT   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    {  return  static_cast < size_t > ( __v ) ;  }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					} ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					template  < >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					struct  spp_hash < unsigned  char >  :  public  std : : unary_function < unsigned  char ,  size_t >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					{  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    SPP_INLINE  size_t  operator ( ) ( unsigned  char  __v )  const  SPP_NOEXCEPT  { return  static_cast < size_t > ( __v ) ; }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    SPP_INLINE  size_t  operator ( ) ( unsigned  char  __v )  const  SPP_NOEXCEPT   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    {  return  static_cast < size_t > ( __v ) ;  }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					} ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					template  < >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					struct  spp_hash < wchar_t >  :  public  std : : unary_function < wchar_t ,  size_t >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					{  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    SPP_INLINE  size_t  operator ( ) ( wchar_t  __v )  const  SPP_NOEXCEPT  { return  static_cast < size_t > ( __v ) ; }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    SPP_INLINE  size_t  operator ( ) ( wchar_t  __v )  const  SPP_NOEXCEPT   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    {  return  static_cast < size_t > ( __v ) ;  }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					} ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					template  < >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					struct  spp_hash < shor t>  :  public  std : : unary_function < shor t,  size_t >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					struct  spp_hash < int16_ t>  :  public  std : : unary_function < int16_ t,  size_t >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					{  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    SPP_INLINE  size_t  operator ( ) ( short  __v )  const  SPP_NOEXCEPT  { return  static_cast < size_t > ( __v ) ; }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    SPP_INLINE  size_t  operator ( ) ( int16_t  __v )  const  SPP_NOEXCEPT   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    {  return  spp_mix_32 ( static_cast < uint32_t > ( __v ) ) ;  }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					} ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					template  < >   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					struct  spp_hash < unsigned  shor t>  :  public  std : : unary_function < unsigned  shor t,  size_t >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					struct  spp_hash < uint16_ t>  :  public  std : : unary_function < uint16_ t,  size_t >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					{  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    SPP_INLINE  size_t  operator ( ) ( unsigned  short  __v )  const  SPP_NOEXCEPT  { return  static_cast < size_t > ( __v ) ; }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    SPP_INLINE  size_t  operator ( ) ( uint16_t  __v )  const  SPP_NOEXCEPT   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    {  return  spp_mix_32 ( static_cast < uint32_t > ( __v ) ) ;  }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					} ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					template  < >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					struct  spp_hash < in t>  :  public  std : : unary_function < in t,  size_t >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					struct  spp_hash < int32_ t>  :  public  std : : unary_function < int32_ t,  size_t >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					{  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    SPP_INLINE  size_t  operator ( ) ( int  __v )  const  SPP_NOEXCEPT  { return  static_cast < size_t > ( __v ) ; }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    SPP_INLINE  size_t  operator ( ) ( int32_t  __v )  const  SPP_NOEXCEPT   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    {  return  spp_mix_32 ( static_cast < uint32_t > ( __v ) ) ;  }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					} ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					template  < >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					struct  spp_hash < unsigned  in t>  :  public  std : : unary_function < unsigned  in t,  size_t >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					struct  spp_hash < uint32_ t>  :  public  std : : unary_function < uint32_ t,  size_t >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					{  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    SPP_INLINE  size_t  operator ( ) ( unsigned  int  __v )  const  SPP_NOEXCEPT  { return  static_cast < size_t > ( __v ) ; }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    SPP_INLINE  size_t  operator ( ) ( uint32_t  __v )  const  SPP_NOEXCEPT   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    {  return  spp_mix_32 ( static_cast < uint32_t > ( __v ) ) ;  }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					} ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					template  < >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					struct  spp_hash < long >  :  public  std : : unary_function < long ,  size_t >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					struct  spp_hash < int64_t >  :  public  std : : unary_function < int64_t ,  size_t >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					{  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    SPP_INLINE  size_t  operator ( ) ( long  __v )  const  SPP_NOEXCEPT  { return  static_cast < size_t > ( __v ) ; }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    SPP_INLINE  size_t  operator ( ) ( int64_t  __v )  const  SPP_NOEXCEPT   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    {  return  spp_mix_64 ( static_cast < uint64_t > ( __v ) ) ;  }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					} ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					template  < >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					struct  spp_hash < unsigned  long >  :  public  std : : unary_function < unsigned  long ,  size_t >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					struct  spp_hash < uint64_t >  :  public  std : : unary_function < uint64_t ,  size_t >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					{  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    SPP_INLINE  size_t  operator ( ) ( unsigned  long  __v )  const  SPP_NOEXCEPT  { return  static_cast < size_t > ( __v ) ; }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    SPP_INLINE  size_t  operator ( ) ( uint64_t  __v )  const  SPP_NOEXCEPT   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    {  return  spp_mix_64 ( static_cast < uint64_t > ( __v ) ) ;  }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					} ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					template  < >  
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -1033,22 +1073,20 @@ struct spp_hash<float> : public std::unary_function<float, size_t> 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        / /  - 0.0  and  0.0  should  return  same  hash  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        uint32_t  * as_int  =  reinterpret_cast < uint32_t  * > ( & __v ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        return  ( __v  = =  0 )  ?  static_cast < size_t > ( 0 )  :  static_cast < size_t >  ( * as_int ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        return  ( __v  = =  0 )  ?  static_cast < size_t > ( 0 )  :  spp_mix_32  ( * as_int ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					} ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					#if 0  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					/ /  todo :  we  should  not  ignore  half  of  the  double  = >  see  libcxx / include / functional  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					template  < >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					struct  spp_hash < double >  :  public  std : : unary_function < double ,  size_t >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					{  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    SPP_INLINE  size_t  operator ( ) ( double  __v )  const  SPP_NOEXCEPT  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        / /  - 0.0  and  0.0  should  return  same  hash  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        return  ( __v  = =  0 )  ?  ( size_t ) 0  :  ( size_t ) * ( ( uint64_t  * ) & __v ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        uint64_t  * as_int  =  reinterpret_cast < uint64_t  * > ( & __v ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        return  ( __v  = =  0 )  ?  static_cast < size_t > ( 0 )  :  spp_mix_64 ( * as_int ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					} ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					# endif  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					template  < class  T ,  int  sz >  struct  Combiner  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					{  
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				
					@ -1080,7 +1118,7 @@ inline void hash_combine(std::size_t& seed, T const& v) 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    combiner ( seed ,  hasher ( v ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					}  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					} ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					}  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					# endif  / /  spp_utils_h_guard_  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				
					@ -1412,30 +1450,36 @@ namespace sparsehash_internal 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  Settings  contains  parameters  for  growing  and  shrinking  the  table .  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  It  also  packages  zero - size  functor  ( ie .  hasher ) .  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  It  does  some  munging  of  the  hash  value  in  cases  where  we  think  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  ( fear )  the  original  hash  function  might  not  be  very  good .   In  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  particular ,  the  default  hash  of  pointers  is  the  identity  hash ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  so  probably  all  the  low  bits  are  0.   We  identify  when  we  think  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  we ' re  hashing  a  pointer ,  and  chop  off  the  low  bits .   Note  this  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  isn ' t  perfect :  even  when  the  key  is  a  pointer ,  we  can ' t  tell  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  for  sure  that  the  hash  is  the  identity  hash .   If  it ' s  not ,  this  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  is  needless  work  ( and  possibly ,  though  not  likely ,  harmful ) .  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  It  does  some  munging  of  the  hash  value  for  the  cases  where   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  the  original  hash  function  is  not  be  very  good .  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    template < typename  Key ,  typename  HashFunc ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					             typename  SizeType ,  int  HT_MIN_BUCKETS >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    template < typename  Key ,  typename  HashFunc ,  typename  SizeType ,  int  HT_MIN_BUCKETS >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    class  sh_hashtable_settings  :  public  HashFunc   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    private :  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					# ifndef SPP_MIX_HASH  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        template  < class  T ,  int  sz >  struct  Mixer  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            inline  T  operator ( ) ( T  h )  const  {  return  h ;  }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        } ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					# else  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        template  < class  T ,  int  sz >  struct  Mixer  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            inline  T  operator ( ) ( T  h )  const ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        } ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        template  < class  T >  struct  Mixer < T ,  4 >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					          template  < class  T >  struct  Mixer < T ,  4 >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            inline  T  operator ( ) ( T  h )  const  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                return  h  +  ( h  > >  7 )  +  ( h  > >  13 )  +  ( h  > >  23 ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                / /  from  Thomas  Wang  -  https : / / gist . github . com / badboy / 6267743  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                / /  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                h  =  ( h  ^  61 )  ^  ( h  > >  16 ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                h  =  h  +  ( h  < <  3 ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                h  =  h  ^  ( h  > >  4 ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                h  =  h  *  0x27d4eb2d ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                h  =  h  ^  ( h  > >  15 ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                return  h ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        } ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -1443,9 +1487,19 @@ namespace sparsehash_internal 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            inline  T  operator ( ) ( T  h )  const  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                return  h  +  ( h  > >  7 )  +  ( h  > >  13 )  +  ( h  > >  23 )  +  ( h  > >  32 ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                / /  from  Thomas  Wang  -  https : / / gist . github . com / badboy / 6267743  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                / /  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                h  =  ( ~ h )  +  ( h  < <  21 ) ;               / /  h  =  ( h  < <  21 )  -  h  -  1 ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                h  =  h  ^  ( h  > >  24 ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                h  =  ( h  +  ( h  < <  3 ) )  +  ( h  < <  8 ) ;      / /  h  *  265  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                h  =  h  ^  ( h  > >  14 ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                h  =  ( h  +  ( h  < <  2 ) )  +  ( h  < <  4 ) ;      / /  h  *  21  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                h  =  h  ^  ( h  > >  28 ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                h  =  h  +  ( h  < <  31 ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                return  h ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        } ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					# endif  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    public :  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        typedef  Key  key_type ;  
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				
					@ -1507,8 +1561,8 @@ namespace sparsehash_internal 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        / /  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        void  set_resizing_parameters ( float  shrink ,  float  grow )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            assert ( shrink  > =  0.0 ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            assert ( grow  < =  1.0 ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            assert ( shrink  > =  0.0f  ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            assert ( grow  < =  1.0f  ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            if  ( shrink  >  grow / 2.0f )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                shrink  =  grow  /  2.0f ;      / /  otherwise  we  thrash  hashtable  size  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            set_shrink_factor ( shrink ) ;  
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				
					@ -1724,34 +1778,6 @@ template <class T, class U> struct is_relocatable<std::pair<T, U> > : 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					/ /  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					/ /  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					template  < class  tabletype >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					class  table_element_adaptor   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					{  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					public :  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    typedef  typename  tabletype : : value_type  value_type ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    typedef  typename  tabletype : : size_type   size_type ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    typedef  typename  tabletype : : reference   reference ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    typedef  typename  tabletype : : pointer     pointer ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    table_element_adaptor ( tabletype  * tbl ,  size_type  p )  :  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        table ( tbl ) ,  pos ( p )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    {  }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    table_element_adaptor &  operator = ( const  value_type  & val )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        table - > set ( pos ,  val ,  false ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        return  * this ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    operator  value_type ( )  {  return  table - > get ( pos ) ;  }    / /  we  look  like  a  value  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    pointer  operator &  ( )  {  return  & table - > mutating_get ( pos ) ;  }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					private :  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    tabletype *  table ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    size_type  pos ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					} ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					/ /  Our  iterator  as  simple  as  iterators  can  be :  basically  it ' s  just  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					/ /  the  index  into  our  table .   Dereference ,  the  only  complicated  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					/ /  thing ,  we  punt  to  the  table  class .   This  just  goes  to  show  how  
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -1774,23 +1800,11 @@ public: 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    typedef  typename  tabletype : : value_type        value_type ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    typedef  typename  tabletype : : difference_type   difference_type ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    typedef  typename  tabletype : : size_type         size_type ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    typedef  table_element_adaptor < tabletype >      reference ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    typedef  table_element_adaptor < tabletype > *     pointer ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    explicit  table_iterator ( tabletype  * tbl  =  0 ,  size_type  p  =  0 )  :   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        table ( tbl ) ,  pos ( p )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    {  }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  The  main  thing  our  iterator  does  is  dereference .   If  the  table  entry  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  we  point  to  is  empty ,  we  return  the  default  value  type .  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  This  is  the  big  different  function  from  the  const  iterator .  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    reference  operator * ( )              
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        return  table_element_adaptor < tabletype > ( table ,  pos ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    pointer  operator - > ( )   {  return  & ( operator * ( ) ) ;  }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  Helper  function  to  assert  things  are  ok ;  eg  pos  is  still  in  range  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    void  check ( )  const   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    {  
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				
					@ -1834,11 +1848,6 @@ public: 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        return  pos  -  it . pos ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    reference  operator [ ] ( difference_type  n )  const   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        return  * ( * this  +  n ) ;             / /  simple  though  not  totally  efficient  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  Comparisons .  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    bool  operator = = ( const  iterator &  it )  const   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    {  
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				
					@ -2306,7 +2315,6 @@ public: 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    typedef  value_type *                                     pointer ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    typedef  const  value_type *                               const_pointer ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    typedef  table_element_adaptor < sparsegroup < T ,  Alloc >  >   element_adaptor ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    typedef  uint8_t                                         size_type ;         / /  max  #  of  buckets  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  These  are  our  special  iterators ,  that  go  over  non - empty  buckets  in  a  
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -2332,16 +2340,6 @@ public: 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    const_reverse_ne_iterator  ne_rend ( )  const     {  return  const_reverse_ne_iterator ( ne_cbegin ( ) ) ;   }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    const_reverse_ne_iterator  ne_crend ( )  const    {  return  const_reverse_ne_iterator ( ne_cbegin ( ) ) ;   }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  This  gives  us  the  " default "  value  to  return  for  an  empty  bucket .  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  We  just  use  the  default  constructor  on  T ,  the  template  type  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    const_reference  default_value ( )  const   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        static  value_type  defaultval  =  value_type ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        return  defaultval ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					private :  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  T  can  be  std : : pair < K ,  V > ,  but  we  need  to  return  std : : pair < const  K ,  V >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				
					@ -2566,16 +2564,6 @@ public: 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  We  also  may  want  to  know  how  many  * used *  buckets  there  are  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    size_type  num_nonempty ( )  const    {  return  ( size_type ) _num_items ( ) ;  }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  get ( ) / set ( )  are  explicitly  const / non - const .   You  can  use  [ ]  if  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  you  want  something  that  can  be  either  ( potentially  more  expensive ) .  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    const_reference  get ( size_type  i )  const   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        if  ( _bmtest ( i ) )            / /  bucket  i  is  occupied  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            return  ( const_reference ) _group [ pos_to_offset ( i ) ] ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        else  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            return  default_value ( ) ;   / /  return  the  default  reference  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  TODO ( csilvers ) :  make  protected  +  friend  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  This  is  used  by  sparse_hashtable  to  get  an  element  from  the  table  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  when  we  know  it  exists .  
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -2587,47 +2575,52 @@ public: 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    typedef  std : : pair < mutable_pointer ,  bool >  SetResult ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  returns  a  reference  which  can  be  assigned ,  so  we  have  to  create  an  entry  if  not   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  already  there  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    reference  mutating_get ( Alloc  & alloc ,  size_type  i )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        / /  fills  bucket  i  before  getting  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        if  ( ! _bmtest ( i ) )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            SetResult  sr  =  set ( alloc ,  i ,  false ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            if  ( ! sr . second )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                : : new  ( sr . first )  mutable_value_type ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            return  * ( ( pointer ) sr . first ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					private :  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    typedef  spp_ : : integral_constant < bool ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                    ( spp_ : : is_relocatable < value_type > : : value  & &  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                     spp_ : : is_same < allocator_type ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                                   spp_ : : libc_allocator_with_realloc < mutable_value_type >  > : : value ) >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            realloc_and_memmove_ok ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        return  _group [ pos_to_offset ( i ) ] ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  - - - - - - - - - - - - - - - - - - - - - - - - -  memory  at  * p  is  uninitialized  = >  need  to  construct  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    void  _init_val ( mutable_value_type  * p ,  reference  val )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					# if !defined(SPP_NO_CXX11_RVALUE_REFERENCES)  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        : : new  ( p )  mutable_value_type ( std : : move ( val ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					# else  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        : : new  ( p )  mutable_value_type ( val ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					# endif  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  Syntactic  sugar .   It ' s  easy  to  return  a  const  reference .   To  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  return  a  non - const  reference ,  we  need  to  use  the  assigner  adaptor .  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    const_reference  operator [ ] ( size_type  i )  const   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  - - - - - - - - - - - - - - - - - - - - - - - - -  memory  at  * p  is  uninitialized  = >  need  to  construct  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    void  _init_val ( mutable_value_type  * p ,  const_reference  val )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        return  get ( i ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        : : new  ( p )  mutable_value_type ( val ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    element_adaptor  operator [ ] ( size_type  i )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  memory  at  * p  is  initialized  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    void  _set_val ( mutable_value_type  * p ,  reference  val )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        return  element_adaptor ( this ,  i ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					# if !defined(SPP_NO_CXX11_RVALUE_REFERENCES)  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        * p  =  std : : move ( val ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					# else  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        using  std : : swap ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        swap ( * p ,  spp_mutable_ref ( val ) ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					# endif  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					private :  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    typedef  spp_ : : integral_constant < bool ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                    ( spp_ : : is_relocatable < value_type > : : value  & &  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                     spp_ : : is_same < allocator_type ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                                   spp_ : : libc_allocator_with_realloc < mutable_value_type >  > : : value ) >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            realloc_and_memmove_ok ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  memory  at  * p  is  initialized  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    void  _set_val ( mutable_value_type  * p ,  const_reference  val )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        * p  =  spp_const_mutable_ref ( val ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  Our  default  allocator  -  try  to  merge  memory  buffers  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  right  now  it  uses  Google ' s  traits ,  but  we  should  use  something  like  folly : : IsRelocatable  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  return  true  if  the  slot  was  constructed  ( i . e .  contains  a  valid  mutable_value_type  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    bool  _set_aux ( Alloc  & alloc ,  size_type  offset ,  spp_ : : true_type )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    template  < class  Val >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    void  _set_aux ( Alloc  & alloc ,  size_type  offset ,  Val  & val ,  spp_ : : true_type )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        / / static  int  x = 0 ;   if  ( + + x  <  10 )  printf ( " x \n " ) ;  / /  check  we  are  getting  here  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					         
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -2643,14 +2636,16 @@ private: 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        for  ( uint32_t  i  =  num_items ;  i  >  offset ;  - - i )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            memcpy ( _group  +  i ,  _group  +  i - 1 ,  sizeof ( * _group ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        return  false ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        _init_val ( _group  +  offset ,  val ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  Create  space  at  _group [ offset ] ,  without  special  assumptions  about  value_type  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  and  allocator_type ,  with  a  default  value  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  return  true  if  the  slot  was  constructed  ( i . e .  contains  a  valid  mutable_value_type  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    bool  _set_aux ( Alloc  & alloc ,  size_type  offset ,  spp_ : : false_type )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    template  < class  Val >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    void  _set_aux ( Alloc  & alloc ,  size_type  offset ,  Val  & val ,  spp_ : : false_type )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        uint32_t   num_items  =  _num_items ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        uint32_t   num_alloc  =  _sizing ( num_items ) ;  
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -2659,9 +2654,9 @@ private: 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        if  ( num_items  <  num_alloc )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            / /  create  new  object  at  end  and  rotate  it  to  position  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            : : new  ( & _group [ num_items ] )  mutable_value_type ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            _init_val ( & _group [ num_items ] ,  val ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            std : : rotate ( _group  +  offset ,  _group  +  num_items ,  _group  +  num_items  +  1 ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            return  true  ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            return ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        / /  This  is  valid  because  0  < =  offset  < =  num_items  
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -2674,57 +2669,37 @@ private: 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            std : : uninitialized_copy ( MK_MOVE_IT ( _group  +  offset ) ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                    MK_MOVE_IT ( _group  +  num_items ) ,  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                                    p  +  offset  +  1 ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        _init_val ( p  +  offset ,  val ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        _free_group ( alloc ,  num_alloc ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        _group  =  p ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        return  false ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					public :  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  TODO ( austern ) :  Make  this  exception  safe :  handle  exceptions  from  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  value_type ' s  copy  constructor .  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  return  true  if  the  slot  was  constructed  ( i . e .  contains  a  valid  mutable_value_type )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    bool  _set ( Alloc  & alloc ,  size_type  i ,  size_type  offset ,  bool  erased )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    template  < class  Val >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    void  _set ( Alloc  & alloc ,  size_type  i ,  size_type  offset ,  Val  & val )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        if  ( erased )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            / /  assert ( _bme_test ( i ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            _bme_clear ( i ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        if  ( ! _bmtest ( i ) )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            bool  res  =  _set_aux ( alloc ,  offset ,  realloc_and_memmove_ok ( ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            _set_aux ( alloc ,  offset ,  val ,  realloc_and_memmove_ok ( ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            _incr_num_items ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            _bmset ( i ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            return  res ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        return  true ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        else  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            _set_val ( & _group [ offset ] ,  val ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  This  returns  a  pair  ( first  is  a  pointer  to  the  item ' s  location ,  second  is  whether  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  that  location  is  constructed  ( i . e .  contains  a  valid  mutable_value_type )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    SetResult  set ( Alloc  & alloc ,  size_type  i ,  bool  erased )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        size_type  offset  =  pos_to_offset ( i ) ;    
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        bool  constructed  =   _set ( alloc ,  i ,  offset ,  erased ) ;  / /  may  change  _group  pointer  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        return  std : : make_pair ( _group  +  offset ,  constructed ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					public :  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  used  in  _move_from  ( where  we  can  move  the  old  value  instead  of  copying  it  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    void  move ( Alloc  & alloc ,  size_type  i ,  reference  val )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  This  returns  the  pointer  to  the  inserted  item  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    template  < class  Val >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    pointer  set ( Alloc  & alloc ,  size_type  i ,  Val  & val )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        / /  assert ( ! _bmtest ( i ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        _bme_clear ( i ) ;  / /  in  case  this  was  an  " erased "  location  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        size_type  offset  =  pos_to_offset ( i ) ;   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        if  ( ! _set ( alloc ,  i ,  offset ,  false ) )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            : : new  ( & _group [ offset ] )  mutable_value_type ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        using  std : : swap ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        swap ( _group [ offset ] ,  spp_mutable_ref ( val ) ) ;  / /  called  from  _move_from ,  OK  to  swap  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        size_type  offset  =  pos_to_offset ( i ) ;    
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        _set ( alloc ,  i ,  offset ,  val ) ;             / /  may  change  _group  pointer  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        return  ( pointer ) ( _group  +  offset ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					     
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  We  let  you  see  if  a  bucket  is  non - empty  without  retrieving  it  
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				
					@ -3074,7 +3049,6 @@ public: 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    typedef  table_iterator < sparsetable < T ,  Alloc >  >         iterator ;        / /  defined  with  index  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    typedef  const_table_iterator < sparsetable < T ,  Alloc >  >   const_iterator ;  / /  defined  with  index  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    typedef  table_element_adaptor < sparsetable < T ,  Alloc >  >  element_adaptor ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    typedef  std : : reverse_iterator < const_iterator >          const_reverse_iterator ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    typedef  std : : reverse_iterator < iterator >                reverse_iterator ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				
					@ -3438,14 +3412,6 @@ public: 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        return  which_group ( pos . pos ) . test ( pos_in_group ( pos . pos ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  We  only  return  const_references  because  it ' s  really  hard  to  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  return  something  settable  for  empty  buckets .   Use  set ( )  instead .  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    const_reference  get ( size_type  i )  const   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        assert ( i  <  _table_size ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        return  which_group ( i ) . get ( pos_in_group ( i ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  TODO ( csilvers ) :  make  protected  +  friend  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  This  is  used  by  sparse_hashtable  to  get  an  element  from  the  table  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  when  we  know  it  exists  ( because  the  caller  has  called  test ( i ) ) .  
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -3457,30 +3423,6 @@ public: 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        return  which_group ( i ) . unsafe_get ( pos_in_group ( i ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  TODO ( csilvers ) :  make  protected  +  friend  element_adaptor  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    reference  mutating_get ( size_type  i )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    {     
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        / /  fills  bucket  i  before  getting  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        assert ( i  <  _table_size ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        GroupsReference  grp ( which_group ( i ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        typename  group_type : : size_type  old_numbuckets  =  grp . num_nonempty ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        reference  retval  =  grp . mutating_get ( _alloc ,  pos_in_group ( i ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        _num_buckets  + =  grp . num_nonempty ( )  -  old_numbuckets ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        return  retval ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  Syntactic  sugar .   As  in  sparsegroup ,  the  non - const  version  is  harder  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    const_reference  operator [ ] ( size_type  i )  const   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        return  get ( i ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    element_adaptor  operator [ ] ( size_type  i )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        return  element_adaptor ( this ,  i ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  Needed  for  hashtables ,  gets  as  a  ne_iterator .   Crashes  for  empty  bcks  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    const_ne_iterator  get_iter ( size_type  i )  const   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    {  
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				
					@ -3524,28 +3466,24 @@ public: 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                _first_group [ current_row ] . offset_to_pos ( current_col ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  This  returns  a  reference  to  the  inserted  item  ( which  is  a  copy  of  val )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  The  trick  is  to  figure  out  whether  we ' re  replacing  or  inserting  anew  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    reference  set ( size_type  i ,  const_reference  val ,  bool  erased  =  false )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  Val  can  be  reference  or  const_reference  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    template  < class  Val >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    reference  set ( size_type  i ,  Val  & val )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        assert ( i  <  _table_size ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        group_type  & group  =  which_group ( i ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        typename  group_type : : size_type  old_numbuckets  =  group . num_nonempty ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        typename  group_type : : SetResult  sr ( group . set ( _alloc ,  pos_in_group ( i ) ,  erased ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        if  ( ! sr . second )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            : : new  ( sr . first )  mutable_value_type ( val ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        else  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            * sr . first  =  spp_const_mutable_ref ( val ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        pointer  p ( group . set ( _alloc ,  pos_in_group ( i ) ,  val ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        _num_buckets  + =  group . num_nonempty ( )  -  old_numbuckets ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        return  * ( ( pointer ) sr . first )  ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        return  * p ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  used  in  _move_from  ( where  we  can  move  the  old  value  instead  of  copying  it  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    void  move ( size_type  i ,  reference  val )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        assert ( i  <  _table_size ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        which_group ( i ) . move ( _alloc ,  pos_in_group ( i ) ,  val ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        which_group ( i ) . set ( _alloc ,  pos_in_group ( i ) ,  val ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        + + _num_buckets ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				
					@ -3816,7 +3754,7 @@ private: 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					public :  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    typedef  Key                                         key_type ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    typedef  typename  spp : : cvt < Value > : : type              value_type ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    typedef  HashFcn                                     hasher ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    typedef  HashFcn                                     hasher ;  / /  user  provided  or  spp_hash < Key >   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    typedef  EqualKey                                    key_equal ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    typedef  Alloc                                       allocator_type ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				
					@ -4101,7 +4039,7 @@ private: 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                assert ( num_probes  <  bucket_count ( )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                       & &  " Hashtable is full: an error in key_equal<> or hash<> " ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            table . set ( bucknum ,  * it ,  false ) ;                / /  copies  the  value  to  here  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            table . set ( bucknum ,  * it ) ;                / /  copies  the  value  to  here  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        settings . inc_num_ht_copies ( ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    }  
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				
					@ -4483,7 +4421,8 @@ public: 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  INSERTION  ROUTINES  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					private :  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  Private  method  used  by  insert_noresize  and  find_or_insert .  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    reference  _insert_at ( const_reference  obj ,  size_type  pos ,  bool  erased )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    template  < class  T >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    reference  _insert_at ( T &  obj ,  size_type  pos ,  bool  erased )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        if  ( size ( )  > =  max_size ( ) )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        {  
				
			 
			
		
	
	
		
			
				
					
						
						
						
							
								 
							 
						
					 
				
				 
				
					@ -4494,11 +4433,12 @@ private: 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            assert ( num_deleted ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            - - num_deleted ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        return  table . set ( pos ,  obj ,  erased ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        return  table . set ( pos ,  obj ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  If  you  know  * this  is  big  enough  to  hold  obj ,  use  this  routine  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    std : : pair < iterator ,  bool >  _insert_noresize ( const_reference  obj )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    template  < class  T >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    std : : pair < iterator ,  bool >  _insert_noresize ( T &  obj )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        Position  pos  =  _find_position ( get_key ( obj ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        bool  already_there  =  ( pos . _t  = =  pt_full ) ;  
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				
					@ -4536,17 +4476,13 @@ private: 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					public :  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					#if 0   & &   ! d e f i n e d ( S P P _ N O _ C X X 1 1 _ V A R I A D I C _ T E M P L A T E S  )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					# if !defined(SPP_NO_CXX11_VARIADIC_TEMPLATES ) 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    template  < class . . .  Args >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    pair < iterator ,  bool >  emplace ( Args & & . . .  args )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    std : : pair < iterator ,  bool >  emplace ( Args & & . . .  args )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        return  rep . emplace_unique ( std : : forward < Args > ( args ) . . . ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    template  < class . . .  Args >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    iterator  emplace_hint ( const_iterator  p ,  Args & & . . .  args )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        return  rep . emplace_unique ( std : : forward < Args > ( args ) . . . ) . first ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        _resize_delta ( 1 ) ;    
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        value_type  obj ( std : : forward < Args > ( args ) . . . ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        return  _insert_noresize ( obj ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					# endif  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				
					@ -4589,12 +4525,14 @@ public: 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    / /  needed  to  rehash  to  make  room  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    / /  Since  we  resized ,  we  can ' t  use  pos ,  so  recalculate  where  to  insert .  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    return  * ( _insert_noresize ( default_value ( key ) ) . first ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    value_type  def ( default_value ( key ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    return  * ( _insert_noresize ( def ) . first ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                else   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    / /  no  need  to  rehash ,  insert  right  here  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    return  _insert_at ( default_value ( key ) ,  erased  ?  erased_pos  :  bucknum ,  erased ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    value_type  def ( default_value ( key ) ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                    return  _insert_at ( def ,  erased  ?  erased_pos  :  bucknum ,  erased ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					                }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					            if  ( grp_pos . test ( ) )  
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				
					@ -5153,6 +5091,20 @@ public: 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        return  it - > second ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					# if !defined(SPP_NO_CXX11_VARIADIC_TEMPLATES)  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    template  < class . . .  Args >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    std : : pair < iterator ,  bool >  emplace ( Args & & . . .  args )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        return  rep . emplace ( std : : forward < Args > ( args ) . . . ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    template  < class . . .  Args >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    iterator  emplace_hint ( const_iterator  ,  Args & & . . .  args )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        return  rep . emplace ( std : : forward < Args > ( args ) . . . ) . first ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					# endif  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  Insert  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    / /  - - - - - -  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    std : : pair < iterator ,  bool >   
				
			 
			
		
	
	
		
			
				
					
						
							
								 
							 
						
						
							
								 
							 
						
						
					 
				
				 
				
					@ -5496,17 +5448,17 @@ public: 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    std : : pair < iterator ,  iterator >   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    equal_range ( const  key_type &  key )  const        {  return  rep . equal_range ( key ) ;  }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					#if 0   & &   ! d e f i n e d ( S P P _ N O _ C X X 1 1 _ V A R I A D I C _ T E M P L A T E S  )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					# if !defined(SPP_NO_CXX11_VARIADIC_TEMPLATES ) 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    template  < class . . .  Args >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    pair < iterator ,  bool >  emplace ( Args & & . . .  args )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    std : : pair < iterator ,  bool >  emplace ( Args & & . . .  args )   
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        return  rep . emplace_unique  ( std : : forward < Args > ( args ) . . . ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        return  rep . emplace ( std : : forward < Args > ( args ) . . . ) ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					
 
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    template  < class . . .  Args >  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    iterator  emplace_hint ( const_iterator  p ,  Args & & . . .  args )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    iterator  emplace_hint ( const_iterator  ,  Args & & . . .  args )  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    {  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        return  rep . emplace_unique  ( std : : forward < Args > ( args ) . . . ) . first ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					        return  rep . emplace ( std : : forward < Args > ( args ) . . . ) . first ;  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					    }  
				
			 
			
		
	
		
			
				
					 
					 
				
				 
				
					# endif