1169691Skan// -*- C++ -*-
2169691Skan
3169691Skan// Copyright (C) 2005, 2006 Free Software Foundation, Inc.
4169691Skan//
5169691Skan// This file is part of the GNU ISO C++ Library.  This library is free
6169691Skan// software; you can redistribute it and/or modify it under the terms
7169691Skan// of the GNU General Public License as published by the Free Software
8169691Skan// Foundation; either version 2, or (at your option) any later
9169691Skan// version.
10169691Skan
11169691Skan// This library is distributed in the hope that it will be useful, but
12169691Skan// WITHOUT ANY WARRANTY; without even the implied warranty of
13169691Skan// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14169691Skan// General Public License for more details.
15169691Skan
16169691Skan// You should have received a copy of the GNU General Public License
17169691Skan// along with this library; see the file COPYING.  If not, write to
18169691Skan// the Free Software Foundation, 59 Temple Place - Suite 330, Boston,
19169691Skan// MA 02111-1307, USA.
20169691Skan
21169691Skan// As a special exception, you may use this file as part of a free
22169691Skan// software library without restriction.  Specifically, if other files
23169691Skan// instantiate templates or use macros or inline functions from this
24169691Skan// file, or you compile this file and link it with other files to
25169691Skan// produce an executable, this file does not by itself cause the
26169691Skan// resulting executable to be covered by the GNU General Public
27169691Skan// License.  This exception does not however invalidate any other
28169691Skan// reasons why the executable file might be covered by the GNU General
29169691Skan// Public License.
30169691Skan
31169691Skan// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL.
32169691Skan
33169691Skan// Permission to use, copy, modify, sell, and distribute this software
34169691Skan// is hereby granted without fee, provided that the above copyright
35169691Skan// notice appears in all copies, and that both that copyright notice
36169691Skan// and this permission notice appear in supporting documentation. None
37169691Skan// of the above authors, nor IBM Haifa Research Laboratories, make any
38169691Skan// representation about the suitability of this software for any
39169691Skan// purpose. It is provided "as is" without express or implied
40169691Skan// warranty.
41169691Skan
42169691Skan/**
43169691Skan * @file hash_eq_fn.hpp
44169691Skan * Contains 2 eqivalence functions, one employing a hash value,
45169691Skan *    and one ignoring it.
46169691Skan */
47169691Skan
48169691Skan#ifndef PB_DS_HASH_EQ_FN_HPP
49169691Skan#define PB_DS_HASH_EQ_FN_HPP
50169691Skan
51169691Skan#include <utility>
52169691Skan#include <debug/debug.h>
53169691Skan
54169691Skannamespace pb_ds
55169691Skan{
56169691Skan  namespace detail
57169691Skan  {
58169691Skan    template<typename Key, class Eq_Fn, class Allocator, bool Store_Hash>
59169691Skan    struct hash_eq_fn;
60169691Skan
61169691Skan#define PB_DS_CLASS_T_DEC \
62169691Skan    template<typename Key, class Eq_Fn, class Allocator>
63169691Skan
64169691Skan#define PB_DS_CLASS_C_DEC \
65169691Skan    hash_eq_fn<Key, Eq_Fn, Allocator, false>
66169691Skan
67169691Skan    /**
68169691Skan     * Specialization 1- The client requests that hash values not be stored.
69169691Skan     **/
70169691Skan    template<typename Key, class Eq_Fn, class Allocator>
71169691Skan    struct hash_eq_fn<Key, Eq_Fn, Allocator, false> : public Eq_Fn
72169691Skan    {
73169691Skan      typedef Eq_Fn eq_fn_base;
74169691Skan
75169691Skan      typedef typename Allocator::template rebind<Key>::other key_allocator;
76169691Skan
77169691Skan      typedef typename key_allocator::const_reference const_key_reference;
78169691Skan
79169691Skan      hash_eq_fn();
80169691Skan
81169691Skan      hash_eq_fn(const Eq_Fn& r_eq_fn);
82169691Skan
83169691Skan      inline bool
84169691Skan      operator()(const_key_reference r_lhs_key, const_key_reference r_rhs_key) const;
85169691Skan
86169691Skan      inline void
87169691Skan      swap(const PB_DS_CLASS_C_DEC& other);
88169691Skan    };
89169691Skan
90169691Skan    PB_DS_CLASS_T_DEC
91169691Skan    PB_DS_CLASS_C_DEC::
92169691Skan    hash_eq_fn()
93169691Skan    { }
94169691Skan
95169691Skan    PB_DS_CLASS_T_DEC
96169691Skan    inline void
97169691Skan    PB_DS_CLASS_C_DEC::
98169691Skan    swap(const PB_DS_CLASS_C_DEC& other)
99169691Skan    { std::swap((Eq_Fn& )(*this), (Eq_Fn& )other); }
100169691Skan
101169691Skan    PB_DS_CLASS_T_DEC
102169691Skan    PB_DS_CLASS_C_DEC::
103169691Skan    hash_eq_fn(const Eq_Fn& r_eq_fn) :
104169691Skan      Eq_Fn(r_eq_fn)
105169691Skan    { }
106169691Skan
107169691Skan    PB_DS_CLASS_T_DEC
108169691Skan    inline bool
109169691Skan    PB_DS_CLASS_C_DEC::
110169691Skan    operator()(const_key_reference r_lhs_key, const_key_reference r_rhs_key) const
111169691Skan    { return (eq_fn_base::operator()(r_lhs_key, r_rhs_key)); }
112169691Skan
113169691Skan#undef PB_DS_CLASS_T_DEC
114169691Skan#undef PB_DS_CLASS_C_DEC
115169691Skan
116169691Skan#define PB_DS_CLASS_T_DEC \
117169691Skan    template<typename Key, class Eq_Fn, class Allocator>
118169691Skan
119169691Skan#define PB_DS_CLASS_C_DEC \
120169691Skan    hash_eq_fn<Key, Eq_Fn, Allocator, true>
121169691Skan
122169691Skan    /**
123169691Skan     * Specialization 2- The client requests that hash values be stored.
124169691Skan     **/
125169691Skan    template<typename Key, class Eq_Fn, class Allocator>
126169691Skan    struct hash_eq_fn<Key, Eq_Fn, Allocator, true> :
127169691Skan      public Eq_Fn
128169691Skan    {
129169691Skan      typedef typename Allocator::size_type size_type;
130169691Skan
131169691Skan      typedef Eq_Fn eq_fn_base;
132169691Skan
133169691Skan      typedef typename Allocator::template rebind<Key>::other key_allocator;
134169691Skan
135169691Skan      typedef typename key_allocator::const_reference const_key_reference;
136169691Skan
137169691Skan      hash_eq_fn();
138169691Skan
139169691Skan      hash_eq_fn(const Eq_Fn& r_eq_fn);
140169691Skan
141169691Skan      inline bool
142169691Skan      operator()(const_key_reference r_lhs_key, size_type lhs_hash,
143169691Skan		 const_key_reference r_rhs_key, size_type rhs_hash) const;
144169691Skan
145169691Skan      inline void
146169691Skan      swap(const PB_DS_CLASS_C_DEC& other);
147169691Skan    };
148169691Skan
149169691Skan    PB_DS_CLASS_T_DEC
150169691Skan    PB_DS_CLASS_C_DEC::
151169691Skan    hash_eq_fn()
152169691Skan    { }
153169691Skan
154169691Skan    PB_DS_CLASS_T_DEC
155169691Skan    PB_DS_CLASS_C_DEC::
156169691Skan    hash_eq_fn(const Eq_Fn& r_eq_fn) :
157169691Skan      Eq_Fn(r_eq_fn)
158169691Skan    { }
159169691Skan
160169691Skan    PB_DS_CLASS_T_DEC
161169691Skan    inline bool
162169691Skan    PB_DS_CLASS_C_DEC::
163169691Skan    operator()(const_key_reference r_lhs_key, size_type lhs_hash,
164169691Skan	       const_key_reference r_rhs_key, size_type rhs_hash) const
165169691Skan    {
166169691Skan      _GLIBCXX_DEBUG_ASSERT(!eq_fn_base::operator()(r_lhs_key, r_rhs_key)
167169691Skan		            || lhs_hash == rhs_hash);
168169691Skan
169169691Skan      return (lhs_hash == rhs_hash &&
170169691Skan	      eq_fn_base::operator()(r_lhs_key, r_rhs_key));
171169691Skan    }
172169691Skan
173169691Skan    PB_DS_CLASS_T_DEC
174169691Skan    inline void
175169691Skan    PB_DS_CLASS_C_DEC::
176169691Skan    swap(const PB_DS_CLASS_C_DEC& other)
177169691Skan    { std::swap((Eq_Fn& )(*this), (Eq_Fn& )(other)); }
178169691Skan
179169691Skan#undef PB_DS_CLASS_T_DEC
180169691Skan#undef PB_DS_CLASS_C_DEC
181169691Skan
182169691Skan  } // namespace detail
183169691Skan} // namespace pb_ds
184169691Skan
185169691Skan#endif
186