// IBM Open Class Library
//
// Licensed Materials - Property of IBM
//
// (C) Copyright IBM Corporation, 1992, 1997 All Rights Reserved
//
// Revision: 78 1.5.1.8 source/core/collect/iikbhsh.c, collection, ioc.v400, 001006 
#ifndef _IIKBHSH_C_
#define _IIKBHSH_C_

#include <new.h>


#pragma info (nocls, nocnd, nocns, nocnv, noext, nognr, novft)


#ifdef IC_BUILD
#define __IOC_INLINE
#else
#define __IOC_INLINE inline
#endif

// --------------------
// IKeyBagAsHshTableOps
// --------------------

// public members

template <class Element, class Key,
          class ElementOps, class Implementation>
__IOC_INLINE
IKeyBagAsHshTableOps <Element, Key, ElementOps, Implementation>::
IKeyBagAsHshTableOps (INumber numberOfElements)
: Inherited (__isDTSClass (Element)),
  ivElementOps (),
  ivImpl (*this, numberOfElements)
{
}

template <class Element, class Key,
          class ElementOps, class Implementation>
__IOC_INLINE
IKeyBagAsHshTableOps <Element, Key, ElementOps, Implementation>::
IKeyBagAsHshTableOps (INumber numberOfElements, void* opsArg)
: Inherited (__isDTSClass (Element)),
  ivElementOps (opsArg),
  ivImpl (*this, numberOfElements)
{
}

template <class Element, class _Key,
          class ElementOps, class Implementation>
__IOC_INLINE
IKeyBagAsHshTableOps <Element, _Key, ElementOps, Implementation>::
IKeyBagAsHshTableOps
  (IKeyBagAsHshTableOps
    <Element, _Key, ElementOps, Implementation> const& collection)
: Inherited (__isDTSClass (Element)),
  ivElementOps (collection.ivElementOps),
  ivImpl (*this, collection.ivImpl)
{
}

template <class Element, class Key,
          class ElementOps, class Implementation>
__IOC_INLINE
IKeyBagAsHshTableOps <Element, Key, ElementOps, Implementation>::
~IKeyBagAsHshTableOps ()
{
}

template <class Element, class Key,
          class ElementOps, class Implementation>
__IOC_INLINE
void
IKeyBagAsHshTableOps <Element, Key, ElementOps, Implementation>::
Assign (void* element1, void const* element2) const
{ ivElementOps.Assign (*(Element*)element1,
                       *(Element const*)element2);
}

template <class Element, class _Key,
          class ElementOps, class Implementation>
__IOC_INLINE
IACollectionImpl*
IKeyBagAsHshTableOps <Element, _Key, ElementOps, Implementation>::
Clone () const
{ return (Implementation*) *new Self (*this);
}

template <class Element, class Key,
          class ElementOps, class Implementation>
__IOC_INLINE
void*
IKeyBagAsHshTableOps <Element, Key, ElementOps, Implementation>::
CreateNode (void const* element) const
{ void* node = ivElementOps.Allocate (sizeof (Node)

#if defined (__DEBUG_ALLOC__)
                                      , __FILE__, __LINE__
#endif




                                     );
  return new (ivImpl.CheckPointer (node))
    Node (*(Element const*)element);
}

#if ! defined (__INO_STREAMING__)
template <class Element, class Key,
          class ElementOps, class Implementation>
__IOC_INLINE
void*
IKeyBagAsHshTableOps <Element, Key, ElementOps, Implementation>::
CreateNodeWithStreamer(IACollectionStreamer *streamer,
                       IDataStream& fromWhere) const
{ void* node = ivElementOps.Allocate (sizeof (Node)

#if defined (__DEBUG_ALLOC__)
                                      , __FILE__, __LINE__
#endif


                                     );
  ivImpl.CheckPointer (node);
  ((Node*)node)->StreamIn (streamer, fromWhere);
  return node;
}
#endif

template <class Element, class Key,
          class ElementOps, class Implementation>
__IOC_INLINE
void*
IKeyBagAsHshTableOps <Element, Key, ElementOps, Implementation>::
CreateNodes (INumber n, size_t& offset) const
{
#if __IBMCPP__ >= 400
#pragma report(level, E)
#endif
  offset = offsetof(Node, ivElement);
#if __IBMCPP__ >= 400
#pragma report(pop)
#endif
  
  return ivElementOps.Allocate ((size_t) (sizeof (Node*) * n)

#if defined (__DEBUG_ALLOC__)
                                , __FILE__, __LINE__
#endif




                               );
}

template <class Element, class Key,
          class ElementOps, class Implementation>
__IOC_INLINE
void
IKeyBagAsHshTableOps <Element, Key, ElementOps, Implementation>::
DeleteNode (void* node) const
{ ((Node*)node)->~Node ();
  ivElementOps.Deallocate (node

#if defined (__DEBUG_ALLOC__)
                           , __FILE__, __LINE__
#endif

                          );
}

template <class Element, class Key,
          class ElementOps, class Implementation>
__IOC_INLINE
void
IKeyBagAsHshTableOps <Element, Key, ElementOps, Implementation>::
DeleteNodes (void* nodes) const
{ ivElementOps.Deallocate (nodes

#if defined (__DEBUG_ALLOC__)
                           , __FILE__, __LINE__
#endif

                          );
}

template <class Element, class _Key,
          class ElementOps, class Implementation>
__IOC_INLINE
bool
IKeyBagAsHshTableOps <Element, _Key, ElementOps, Implementation>::
EqualKeys (void const* arg1, void const* arg2, IArgType argType) const
{ bool result;
  switch (argType) {
    case kElementElement: {
      result = ivElementOps.keyOps.Equal
        (ivElementOps.Key (*(Element const*)arg1),
         ivElementOps.Key (*(Element const*)arg2));
      break;
    }
    case kElementKey: {
      result = ivElementOps.keyOps.Equal
        (ivElementOps.Key (*(Element const*)arg1),
         IKeyForOps ((_Key const*)arg2));
      break;
    }
   case kKeyKey: {
      result = ivElementOps.keyOps.Equal
        (IKeyForOps ((_Key const*)arg1),
         IKeyForOps ((_Key const*)arg2));
      break;
    }

  }
  return result;
}

template <class Element, class _Key,
          class ElementOps, class Implementation>
__IOC_INLINE
unsigned long
IKeyBagAsHshTableOps <Element, _Key, ElementOps, Implementation>::
HashKey (void const* arg, unsigned long h, IArgType argType) const
{ unsigned long hashValue;
  switch (argType) {
    case kElement: {
      hashValue = ivElementOps.keyOps.Hash
        (ivElementOps.Key (*(Element const*)arg), h);
      break;
    }
    case kKey: {
      hashValue = ivElementOps.keyOps.Hash
        (IKeyForOps ((_Key const*)arg), h);
      break;
    }
  }
  return hashValue;
}

template <class Element, class _Key,
          class ElementOps, class Implementation>
__IOC_INLINE
void*
IKeyBagAsHshTableOps <Element, _Key, ElementOps, Implementation>::
Key (void const* element) const
{ return IKeyFromOps (ivElementOps.Key (*(Element const*)element));
}

template <class Element, class Key,
          class ElementOps, class Implementation>
__IOC_INLINE
IKeyBagAsHshTableOps <Element, Key, ElementOps, Implementation>::
operator Implementation* ()
{ ivImpl.CheckPointer (this);
  return &ivImpl;
}


#pragma info (restore)


#endif // _IIKBHSH_C_
