1// -*- C++ -*-
2
3// Copyright (C) 2005, 2006, 2009 Free Software Foundation, Inc.
4//
5// This file is part of the GNU ISO C++ Library.  This library is free
6// software; you can redistribute it and/or modify it under the terms
7// of the GNU General Public License as published by the Free Software
8// Foundation; either version 3, or (at your option) any later
9// version.
10
11// This library is distributed in the hope that it will be useful, but
12// WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14// General Public License for more details.
15
16// You should have received a copy of the GNU General Public License
17// along with this library; see the file COPYING3.  If not see
18// <http://www.gnu.org/licenses/>.
19
20
21// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL.
22
23// Permission to use, copy, modify, sell, and distribute this software
24// is hereby granted without fee, provided that the above copyright
25// notice appears in all copies, and that both that copyright notice
26// and this permission notice appear in supporting documentation. None
27// of the above authors, nor IBM Haifa Research Laboratories, make any
28// representation about the suitability of this software for any
29// purpose. It is provided "as is" without express or implied
30// warranty.
31
32/**
33 * @file trait.hpp
34 * Contains traits for a random regression test
35 *    for a specific container type.
36 */
37
38#ifndef PB_DS_REGRESSION_TEST_TRAIT_HPP
39#define PB_DS_REGRESSION_TEST_TRAIT_HPP
40
41#include <regression/trait/erase_if_fn.hpp>
42#include <regression/trait/assoc/to_string.hpp>
43#include <regression/trait/assoc/type_trait.hpp>
44#include <regression/trait/assoc/native_type_trait.hpp>
45#include <regression/trait/assoc/resize_trait.hpp>
46#include <regression/trait/assoc/get_set_loads_trait.hpp>
47#include <regression/trait/assoc/get_set_load_trait.hpp>
48#include <regression/trait/assoc/node_update_trait.hpp>
49
50namespace __gnu_pbds
51{
52namespace test
53{
54namespace detail
55{
56
57#define PB_DS_CLASS_T_DEC \
58  template<typename Cntnr>
59
60#define PB_DS_CLASS_C_DEC \
61  regression_test_traits<Cntnr>
62
63#define PB_DS_TYPE_TRAITS_C_DEC \
64  regression_test_type_traits<Cntnr>
65
66#define PB_DS_NATIVE_TYPE_TRAITS_C_DEC \
67  native_type_traits<typename PB_DS_TYPE_TRAITS_C_DEC::key_type, \
68		     typename PB_DS_TYPE_TRAITS_C_DEC::mapped_type, \
69		     typename Cntnr::allocator_type>
70
71#define PB_DS_RESIZE_TRAITS_C_DEC \
72  regression_test_resize_traits<Cntnr, typename Cntnr::container_category>
73
74#define PB_DS_SET_LOADS_TRAITS_C_DEC \
75  regression_test_get_set_loacontainer_traits<Cntnr,	\
76					  typename Cntnr::container_category>
77
78#define PB_DS_SET_LOAD_TRAITS_C_DEC \
79  regression_test_get_set_load_traits<Cntnr,typename Cntnr::container_category>
80
81#define PB_DS_NODE_UPDATOR_TRAITS_C_DEC \
82  regression_test_node_update_traits<Cntnr, typename Cntnr::container_category>
83
84  template<typename Cntnr>
85  struct regression_test_traits : private PB_DS_TYPE_TRAITS_C_DEC,
86				  private PB_DS_NATIVE_TYPE_TRAITS_C_DEC,
87				  private PB_DS_RESIZE_TRAITS_C_DEC,
88				  private PB_DS_NODE_UPDATOR_TRAITS_C_DEC,
89				  private PB_DS_SET_LOADS_TRAITS_C_DEC,
90				  private PB_DS_SET_LOAD_TRAITS_C_DEC
91  {
92  private:
93    typedef PB_DS_NATIVE_TYPE_TRAITS_C_DEC native_type_traits_base;
94    typedef PB_DS_TYPE_TRAITS_C_DEC type_traits_base;
95
96  public:
97    typedef typename Cntnr::value_type value_type;
98    typedef typename Cntnr::const_reference const_reference;
99    typedef typename PB_DS_NATIVE_TYPE_TRAITS_C_DEC::type native_type;
100    typedef typename native_type::value_type native_value_type;
101
102    // Only associative containers.
103    typedef typename Cntnr::key_type key_type;
104    typedef typename Cntnr::const_key_reference const_key_reference;
105    typedef typename native_type::key_type native_key_type;
106
107    enum
108      {
109	resize = PB_DS_RESIZE_TRAITS_C_DEC::value,
110	get_set_loads = PB_DS_SET_LOADS_TRAITS_C_DEC::value,
111	get_set_load = PB_DS_SET_LOAD_TRAITS_C_DEC::value,
112	order_statistics = PB_DS_NODE_UPDATOR_TRAITS_C_DEC::order_statistics,
113	prefix_search = PB_DS_NODE_UPDATOR_TRAITS_C_DEC::prefix_search
114      };
115
116    template<typename T>
117    struct erase_if_fn : public regression_test_erase_if_fn<T>
118    { };
119
120    static size_t
121    erase_if(native_type& r_native_c)
122    {
123      typedef regression_test_erase_if_fn<native_value_type> erase_if_fn;
124      typename native_type::iterator it = r_native_c.begin();
125      size_t num_ersd = 0;
126      while (it != r_native_c.end())
127	if (erase_if_fn()(*it))
128	  {
129	    ++num_ersd;
130	    r_native_c.erase(it);
131	    it = r_native_c.begin();
132	  }
133	else
134	  ++it;
135      return num_ersd;
136    }
137
138    static void
139    print_container(const Cntnr& r_c, std::ostream& r_os)
140    { PB_DS_TYPE_TRAITS_C_DEC::print_container(r_c, r_os); }
141
142    template<typename Gen>
143    static key_type
144    generate_key(Gen& r_gen, size_t max)
145    { return PB_DS_TYPE_TRAITS_C_DEC::generate_key(r_gen, max); }
146
147    template<typename Gen>
148    static value_type
149    generate_value(Gen& r_gen, size_t max)
150    { return PB_DS_TYPE_TRAITS_C_DEC::generate_value(r_gen, max); }
151
152    static const_key_reference
153    extract_key(const_reference r_val)
154    { return type_traits_base::extract_key(r_val); }
155
156    static native_key_type
157    native_key(const_key_reference r_key)
158    { return native_type_traits_base::native_key(r_key); }
159
160    static native_value_type
161    native_value(const_reference r_val)
162    { return native_type_traits_base::native_value(r_val); }
163
164    static const native_key_type&
165    extract_native_key(const native_value_type& r_val)
166    { return native_type_traits_base::extract_key(r_val); }
167
168    static bool
169    cmp(const_reference r_val, const native_value_type& r_native_val)
170    { return val_to_string(r_val) == native_val_to_string(r_native_val); }
171
172    static std::string
173    val_to_string(const_reference r_val)
174    { return to_string(r_val); }
175
176    static std::string
177    key_to_string(const_key_reference r_key)
178    { return to_string(r_key); }
179
180    static std::string
181    native_val_to_string(const native_value_type& r_native_val)
182    { return to_string(r_native_val); }
183
184    static bool
185    prefix_match(const_key_reference r_key, const std::string& r_native_key)
186    {
187      const size_t len = std::min(r_key.length(), r_native_key.length());
188      const std::string substr = r_native_key.substr(0, len);
189      return substr == static_cast<const std::string&>(r_key);
190    }
191  };
192
193#undef PB_DS_TYPE_TRAITS_C_DEC
194#undef PB_DS_NATIVE_TYPE_TRAITS_C_DEC
195#undef PB_DS_RESIZE_TRAITS_C_DEC
196#undef PB_DS_SET_LOADS_TRAITS_C_DEC
197#undef PB_DS_SET_LOAD_TRAITS_C_DEC
198#undef PB_DS_NODE_UPDATOR_TRAITS_C_DEC
199#undef PB_DS_CLASS_T_DEC
200#undef PB_DS_CLASS_C_DEC
201
202} // namespace detail
203} // namespace test
204} // namespace __gnu_pbds
205
206#endif
207