111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// -*- C++ -*-
211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Copyright (C) 2005-2014 Free Software Foundation, Inc.
411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert//
511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// This file is part of the GNU ISO C++ Library.  This library is free
611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// software; you can redistribute it and/or modify it under the terms
711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// of the GNU General Public License as published by the Free Software
811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Foundation; either version 3, or (at your option) any later
911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// version.
1011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
1111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// This library is distributed in the hope that it will be useful, but
1211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// WITHOUT ANY WARRANTY; without even the implied warranty of
1311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
1411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// General Public License for more details.
1511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
1611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Under Section 7 of GPL version 3, you are granted additional
1711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// permissions described in the GCC Runtime Library Exception, version
1811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// 3.1, as published by the Free Software Foundation.
1911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
2011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// You should have received a copy of the GNU General Public License and
2111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// a copy of the GCC Runtime Library Exception along with this program;
2211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
2311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// <http://www.gnu.org/licenses/>.
2411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
2511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Copyright (C) 2004 Ami Tavory and Vladimir Dreizin, IBM-HRL.
2611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
2711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// Permission to use, copy, modify, sell, and distribute this software
2811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// is hereby granted without fee, provided that the above copyright
2911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// notice appears in all copies, and that both that copyright notice
3011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// and this permission notice appear in supporting documentation. None
3111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// of the above authors, nor IBM Haifa Research Laboratories, make any
3211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// representation about the suitability of this software for any
3311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// purpose. It is provided "as is" without express or implied
3411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert// warranty.
3511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
3611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert/** @file ext/throw_allocator.h
3711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *  This file is a GNU extension to the Standard C++ Library.
3811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *
3911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *  Contains two exception-generating types (throw_value, throw_allocator)
4011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *  intended to be used as value and allocator types while testing
4111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *  exception safety in templatized containers and algorithms. The
4211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *  allocator has additional log and debug features. The exception
4311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert *  generated is of type forced_exception_error.
4411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert */
4511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
4611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifndef _THROW_ALLOCATOR_H
4711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#define _THROW_ALLOCATOR_H 1
4811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
4911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include <cmath>
5011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include <ctime>
5111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include <map>
5211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include <string>
5311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include <ostream>
5411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include <stdexcept>
5511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include <utility>
5611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include <bits/functexcept.h>
5711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#include <bits/move.h>
5811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if __cplusplus >= 201103L
5911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# include <functional>
6011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# include <random>
6111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
6211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# include <tr1/functional>
6311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# include <tr1/random>
6411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
6511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
6611cd02dfb91661c65134cac258cf5924270e9d2Dan Albertnamespace __gnu_cxx _GLIBCXX_VISIBILITY(default)
6711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{
6811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert_GLIBCXX_BEGIN_NAMESPACE_VERSION
6911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
7011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  /**
7111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert   *  @brief Thown by exception safety machinery.
7211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert   *  @ingroup exceptions
7311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert   */
7411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  struct forced_error : public std::exception
7511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  { };
7611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
7711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // Substitute for forced_error object when -fno-exceptions.
7811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  inline void
7911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  __throw_forced_error()
8011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  { _GLIBCXX_THROW_OR_ABORT(forced_error()); }
8111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
8211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  /**
8311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert   *  @brief Base class for checking address and label information
8411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert   *  about allocations. Create a std::map between the allocated
8511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert   *  address (void*) and a datum for annotations, which are a pair of
8611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert   *  numbers corresponding to label and allocated size.
8711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert   */
8811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  struct annotate_base
8911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  {
9011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    annotate_base()
9111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
9211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      label();
9311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      map_alloc();
9411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
9511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
9611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    static void
9711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    set_label(size_t l)
9811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    { label() = l; }
9911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
10011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    static size_t
10111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    get_label()
10211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    { return label(); }
10311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
10411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    void
10511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    insert(void* p, size_t size)
10611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
10711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      if (!p)
10811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	{
10911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  std::string error("annotate_base::insert null insert!\n");
11011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  log_to_string(error, make_entry(p, size));
11111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  std::__throw_logic_error(error.c_str());
11211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
11311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
11411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      const_iterator found = map_alloc().find(p);
11511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      if (found != map_alloc().end())
11611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	{
11711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  std::string error("annotate_base::insert double insert!\n");
11811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  log_to_string(error, make_entry(p, size));
11911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  log_to_string(error, *found);
12011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  std::__throw_logic_error(error.c_str());
12111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
12211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
12311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      map_alloc().insert(make_entry(p, size));
12411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
12511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
12611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    void
12711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    erase(void* p, size_t size)
12811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
12911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      check_allocated(p, size);
13011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      map_alloc().erase(p);
13111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
13211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
13311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if __cplusplus >= 201103L
13411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    void
13511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    insert_construct(void* p)
13611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
13711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      if (!p)
13811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	{
13911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  std::string error("annotate_base::insert_construct null!\n");
14011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  std::__throw_logic_error(error.c_str());
14111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
14211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
14311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      auto found = map_construct().find(p);
14411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      if (found != map_construct().end())
14511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	{
14611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  std::string error("annotate_base::insert_construct double insert!\n");
14711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  log_to_string(error, std::make_pair(p, get_label()));
14811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  log_to_string(error, *found);
14911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  std::__throw_logic_error(error.c_str());
15011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
15111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
15211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      map_construct().insert(std::make_pair(p, get_label()));
15311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
15411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
15511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    void
15611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    erase_construct(void* p)
15711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
15811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      check_constructed(p);
15911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      map_construct().erase(p);
16011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
16111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
16211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
16311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // See if a particular address and allocation size has been saved.
16411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    inline void
16511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    check_allocated(void* p, size_t size)
16611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
16711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      const_iterator found = map_alloc().find(p);
16811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      if (found == map_alloc().end())
16911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	{
17011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  std::string error("annotate_base::check_allocated by value "
17111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			    "null erase!\n");
17211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  log_to_string(error, make_entry(p, size));
17311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  std::__throw_logic_error(error.c_str());
17411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
17511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
17611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      if (found->second.second != size)
17711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	{
17811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  std::string error("annotate_base::check_allocated by value "
17911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			    "wrong-size erase!\n");
18011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  log_to_string(error, make_entry(p, size));
18111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  log_to_string(error, *found);
18211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  std::__throw_logic_error(error.c_str());
18311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
18411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
18511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
18611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // See if a given label has been allocated.
18711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    inline void
18811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    check(size_t label)
18911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
19011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      std::string found;
19111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      {
19211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	const_iterator beg = map_alloc().begin();
19311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	const_iterator end = map_alloc().end();
19411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	while (beg != end)
19511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  {
19611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	    if (beg->second.first == label)
19711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	      log_to_string(found, *beg);
19811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	    ++beg;
19911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  }
20011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      }
20111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
20211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if __cplusplus >= 201103L
20311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      {
20411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	auto beg = map_construct().begin();
20511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	auto end = map_construct().end();
20611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	while (beg != end)
20711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  {
20811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	    if (beg->second == label)
20911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	      log_to_string(found, *beg);
21011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	    ++beg;
21111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  }
21211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      }
21311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
21411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
21511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      if (!found.empty())
21611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	{
21711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  std::string error("annotate_base::check by label\n");
21811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  error += found;
21911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  std::__throw_logic_error(error.c_str());
22011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
22111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
22211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
22311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // See if there is anything left allocated or constructed.
22411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    inline static void
22511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    check()
22611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
22711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      std::string found;
22811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      {
22911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	const_iterator beg = map_alloc().begin();
23011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	const_iterator end = map_alloc().end();
23111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	while (beg != end)
23211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  {
23311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	    log_to_string(found, *beg);
23411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	    ++beg;
23511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  }
23611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      }
23711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
23811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if __cplusplus >= 201103L
23911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      {
24011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	auto beg = map_construct().begin();
24111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	auto end = map_construct().end();
24211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	while (beg != end)
24311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  {
24411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	    log_to_string(found, *beg);
24511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	    ++beg;
24611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  }
24711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      }
24811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
24911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
25011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      if (!found.empty())
25111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	{
25211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  std::string error("annotate_base::check \n");
25311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  error += found;
25411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  std::__throw_logic_error(error.c_str());
25511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
25611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
25711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
25811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if __cplusplus >= 201103L
25911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    inline void
26011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    check_constructed(void* p)
26111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
26211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      auto found = map_construct().find(p);
26311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      if (found == map_construct().end())
26411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	{
26511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  std::string error("annotate_base::check_constructed not "
26611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert			    "constructed!\n");
26711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  log_to_string(error, std::make_pair(p, get_label()));
26811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  std::__throw_logic_error(error.c_str());
26911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
27011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
27111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
27211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    inline void
27311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    check_constructed(size_t label)
27411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
27511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      auto beg = map_construct().begin();
27611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      auto end = map_construct().end();
27711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      std::string found;
27811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      while (beg != end)
27911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	{
28011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  if (beg->second == label)
28111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	    log_to_string(found, *beg);
28211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  ++beg;
28311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
28411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
28511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      if (!found.empty())
28611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	{
28711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  std::string error("annotate_base::check_constructed by label\n");
28811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  error += found;
28911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  std::__throw_logic_error(error.c_str());
29011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
29111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
29211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
29311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
29411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  private:
29511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    typedef std::pair<size_t, size_t>		data_type;
29611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    typedef std::map<void*, data_type> 		map_alloc_type;
29711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    typedef map_alloc_type::value_type 		entry_type;
29811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    typedef map_alloc_type::const_iterator 		const_iterator;
29911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    typedef map_alloc_type::const_reference 		const_reference;
30011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if __cplusplus >= 201103L
30111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    typedef std::map<void*, size_t>		map_construct_type;
30211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
30311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
30411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    friend std::ostream&
30511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    operator<<(std::ostream&, const annotate_base&);
30611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
30711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    entry_type
30811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    make_entry(void* p, size_t size)
30911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    { return std::make_pair(p, data_type(get_label(), size)); }
31011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
31111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    static void
31211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    log_to_string(std::string& s, const_reference ref)
31311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
31411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      char buf[40];
31511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      const char tab('\t');
31611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      s += "label: ";
31711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      unsigned long l = static_cast<unsigned long>(ref.second.first);
31811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      __builtin_sprintf(buf, "%lu", l);
31911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      s += buf;
32011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      s += tab;
32111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      s += "size: ";
32211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      l = static_cast<unsigned long>(ref.second.second);
32311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      __builtin_sprintf(buf, "%lu", l);
32411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      s += buf;
32511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      s += tab;
32611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      s += "address: ";
32711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      __builtin_sprintf(buf, "%p", ref.first);
32811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      s += buf;
32911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      s += '\n';
33011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
33111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
33211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if __cplusplus >= 201103L
33311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    static void
33411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    log_to_string(std::string& s, const std::pair<const void*, size_t>& ref)
33511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
33611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      char buf[40];
33711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      const char tab('\t');
33811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      s += "label: ";
33911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      unsigned long l = static_cast<unsigned long>(ref.second);
34011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      __builtin_sprintf(buf, "%lu", l);
34111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      s += buf;
34211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      s += tab;
34311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      s += "address: ";
34411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      __builtin_sprintf(buf, "%p", ref.first);
34511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      s += buf;
34611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      s += '\n';
34711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
34811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
34911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
35011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    static size_t&
35111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    label()
35211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
35311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      static size_t _S_label(std::numeric_limits<size_t>::max());
35411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      return _S_label;
35511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
35611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
35711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    static map_alloc_type&
35811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    map_alloc()
35911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
36011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      static map_alloc_type _S_map;
36111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      return _S_map;
36211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
36311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
36411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if __cplusplus >= 201103L
36511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    static map_construct_type&
36611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    map_construct()
36711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
36811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      static map_construct_type _S_map;
36911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      return _S_map;
37011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
37111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
37211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  };
37311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
37411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  inline std::ostream&
37511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  operator<<(std::ostream& os, const annotate_base& __b)
37611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  {
37711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    std::string error;
37811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    typedef annotate_base base_type;
37911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
38011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      base_type::const_iterator beg = __b.map_alloc().begin();
38111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      base_type::const_iterator end = __b.map_alloc().end();
38211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      for (; beg != end; ++beg)
38311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	__b.log_to_string(error, *beg);
38411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
38511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if __cplusplus >= 201103L
38611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
38711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      auto beg = __b.map_construct().begin();
38811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      auto end = __b.map_construct().end();
38911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      for (; beg != end; ++beg)
39011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	__b.log_to_string(error, *beg);
39111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
39211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
39311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    return os << error;
39411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  }
39511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
39611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
39711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  /**
39811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert   *  @brief Base struct for condition policy.
39911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert   *
40011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert   * Requires a public member function with the signature
40111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert   * void throw_conditionally()
40211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert   */
40311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  struct condition_base
40411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  {
40511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    virtual ~condition_base() { };
40611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  };
40711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
40811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
40911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  /**
41011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert   *  @brief Base class for incremental control and throw.
41111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert   */
41211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  struct limit_condition : public condition_base
41311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  {
41411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // Scope-level adjustor objects: set limit for throw at the
41511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // beginning of a scope block, and restores to previous limit when
41611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // object is destroyed on exiting the block.
41711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    struct adjustor_base
41811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
41911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    private:
42011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      const size_t _M_orig;
42111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
42211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    public:
42311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      adjustor_base() : _M_orig(limit()) { }
42411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
42511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      virtual
42611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      ~adjustor_base() { set_limit(_M_orig); }
42711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    };
42811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
42911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    /// Never enter the condition.
43011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    struct never_adjustor : public adjustor_base
43111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
43211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      never_adjustor() { set_limit(std::numeric_limits<size_t>::max()); }
43311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    };
43411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
43511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    /// Always enter the condition.
43611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    struct always_adjustor : public adjustor_base
43711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
43811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      always_adjustor() { set_limit(count()); }
43911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    };
44011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
44111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    /// Enter the nth condition.
44211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    struct limit_adjustor : public adjustor_base
44311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
44411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      limit_adjustor(const size_t __l) { set_limit(__l); }
44511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    };
44611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
44711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // Increment _S_count every time called.
44811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // If _S_count matches the limit count, throw.
44911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    static void
45011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    throw_conditionally()
45111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
45211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      if (count() == limit())
45311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	__throw_forced_error();
45411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      ++count();
45511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
45611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
45711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    static size_t&
45811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    count()
45911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
46011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      static size_t _S_count(0);
46111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      return _S_count;
46211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
46311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
46411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    static size_t&
46511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    limit()
46611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
46711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      static size_t _S_limit(std::numeric_limits<size_t>::max());
46811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      return _S_limit;
46911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
47011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
47111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // Zero the throw counter, set limit to argument.
47211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    static void
47311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    set_limit(const size_t __l)
47411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
47511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      limit() = __l;
47611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      count() = 0;
47711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
47811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  };
47911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
48011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
48111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  /**
48211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert   *  @brief Base class for random probability control and throw.
48311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert   */
48411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  struct random_condition : public condition_base
48511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  {
48611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // Scope-level adjustor objects: set probability for throw at the
48711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // beginning of a scope block, and restores to previous
48811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    // probability when object is destroyed on exiting the block.
48911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    struct adjustor_base
49011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
49111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    private:
49211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      const double _M_orig;
49311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
49411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    public:
49511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      adjustor_base() : _M_orig(probability()) { }
49611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
49711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      virtual ~adjustor_base()
49811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      { set_probability(_M_orig); }
49911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    };
50011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
50111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    /// Group condition.
50211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    struct group_adjustor : public adjustor_base
50311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
50411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      group_adjustor(size_t size)
50511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      { set_probability(1 - std::pow(double(1 - probability()),
50611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert				     double(0.5 / (size + 1))));
50711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      }
50811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    };
50911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
51011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    /// Never enter the condition.
51111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    struct never_adjustor : public adjustor_base
51211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
51311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      never_adjustor() { set_probability(0); }
51411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    };
51511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
51611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    /// Always enter the condition.
51711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    struct always_adjustor : public adjustor_base
51811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
51911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      always_adjustor() { set_probability(1); }
52011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    };
52111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
52211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    random_condition()
52311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
52411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      probability();
52511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      engine();
52611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
52711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
52811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    static void
52911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    set_probability(double __p)
53011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    { probability() = __p; }
53111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
53211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    static void
53311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    throw_conditionally()
53411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
53511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      if (generate() < probability())
53611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	__throw_forced_error();
53711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
53811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
53911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    void
54011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    seed(unsigned long __s)
54111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    { engine().seed(__s); }
54211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
54311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  private:
54411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if __cplusplus >= 201103L
54511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    typedef std::uniform_real_distribution<double> 	distribution_type;
54611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    typedef std::mt19937 				engine_type;
54711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
54811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    typedef std::tr1::uniform_real<double> 		distribution_type;
54911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    typedef std::tr1::mt19937 				engine_type;
55011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
55111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
55211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    static double
55311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    generate()
55411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
55511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if __cplusplus >= 201103L
55611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      const distribution_type distribution(0, 1);
55711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      static auto generator = std::bind(distribution, engine());
55811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
55911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      // Use variate_generator to get normalized results.
56011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      typedef std::tr1::variate_generator<engine_type, distribution_type> gen_t;
56111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      distribution_type distribution(0, 1);
56211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      static gen_t generator(engine(), distribution);
56311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
56411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
56511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      double random = generator();
56611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      if (random < distribution.min() || random > distribution.max())
56711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	{
56811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  std::string __s("random_condition::generate");
56911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  __s += "\n";
57011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  __s += "random number generated is: ";
57111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  char buf[40];
57211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  __builtin_sprintf(buf, "%f", random);
57311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  __s += buf;
57411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  std::__throw_out_of_range(__s.c_str());
57511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
57611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
57711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      return random;
57811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
57911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
58011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    static double&
58111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    probability()
58211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
58311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      static double _S_p;
58411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      return _S_p;
58511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
58611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
58711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    static engine_type&
58811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    engine()
58911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
59011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      static engine_type _S_e;
59111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      return _S_e;
59211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
59311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  };
59411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
59511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
59611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  /**
59711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert   *  @brief Class with exception generation control. Intended to be
59811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert   *  used as a value_type in templatized code.
59911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert   *
60011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert   *  Note: Destructor not allowed to throw.
60111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert   */
60211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  template<typename _Cond>
60311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    struct throw_value_base : public _Cond
60411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
60511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      typedef _Cond  				condition_type;
60611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
60711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      using condition_type::throw_conditionally;
60811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
60911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      std::size_t			       	_M_i;
61011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
61111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifndef _GLIBCXX_IS_AGGREGATE
61211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      throw_value_base() : _M_i(0)
61311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      { throw_conditionally(); }
61411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
61511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      throw_value_base(const throw_value_base& __v) : _M_i(__v._M_i)
61611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      { throw_conditionally(); }
61711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
61811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if __cplusplus >= 201103L
61911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      // Shall not throw.
62011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      throw_value_base(throw_value_base&&) = default;
62111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
62211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
62311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      explicit throw_value_base(const std::size_t __i) : _M_i(__i)
62411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      { throw_conditionally(); }
62511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
62611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
62711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      throw_value_base&
62811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      operator=(const throw_value_base& __v)
62911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      {
63011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	throw_conditionally();
63111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	_M_i = __v._M_i;
63211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	return *this;
63311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      }
63411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
63511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if __cplusplus >= 201103L
63611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      // Shall not throw.
63711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      throw_value_base&
63811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      operator=(throw_value_base&&) = default;
63911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
64011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
64111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      throw_value_base&
64211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      operator++()
64311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      {
64411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	throw_conditionally();
64511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	++_M_i;
64611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	return *this;
64711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      }
64811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    };
64911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
65011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  template<typename _Cond>
65111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    inline void
65211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    swap(throw_value_base<_Cond>& __a, throw_value_base<_Cond>& __b)
65311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
65411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      typedef throw_value_base<_Cond> throw_value;
65511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      throw_value::throw_conditionally();
65611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      throw_value orig(__a);
65711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      __a = __b;
65811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      __b = orig;
65911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
66011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
66111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // General instantiable types requirements.
66211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  template<typename _Cond>
66311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    inline bool
66411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    operator==(const throw_value_base<_Cond>& __a,
66511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	       const throw_value_base<_Cond>& __b)
66611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
66711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      typedef throw_value_base<_Cond> throw_value;
66811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      throw_value::throw_conditionally();
66911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      bool __ret = __a._M_i == __b._M_i;
67011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      return __ret;
67111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
67211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
67311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  template<typename _Cond>
67411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    inline bool
67511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    operator<(const throw_value_base<_Cond>& __a,
67611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	      const throw_value_base<_Cond>& __b)
67711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
67811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      typedef throw_value_base<_Cond> throw_value;
67911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      throw_value::throw_conditionally();
68011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      bool __ret = __a._M_i < __b._M_i;
68111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      return __ret;
68211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
68311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
68411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  // Numeric algorithms instantiable types requirements.
68511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  template<typename _Cond>
68611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    inline throw_value_base<_Cond>
68711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    operator+(const throw_value_base<_Cond>& __a,
68811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	      const throw_value_base<_Cond>& __b)
68911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
69011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      typedef throw_value_base<_Cond> throw_value;
69111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      throw_value::throw_conditionally();
69211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      throw_value __ret(__a._M_i + __b._M_i);
69311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      return __ret;
69411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
69511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
69611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  template<typename _Cond>
69711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    inline throw_value_base<_Cond>
69811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    operator-(const throw_value_base<_Cond>& __a,
69911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	      const throw_value_base<_Cond>& __b)
70011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
70111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      typedef throw_value_base<_Cond> throw_value;
70211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      throw_value::throw_conditionally();
70311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      throw_value __ret(__a._M_i - __b._M_i);
70411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      return __ret;
70511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
70611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
70711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  template<typename _Cond>
70811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    inline throw_value_base<_Cond>
70911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    operator*(const throw_value_base<_Cond>& __a,
71011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	      const throw_value_base<_Cond>& __b)
71111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
71211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      typedef throw_value_base<_Cond> throw_value;
71311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      throw_value::throw_conditionally();
71411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      throw_value __ret(__a._M_i * __b._M_i);
71511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      return __ret;
71611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
71711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
71811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
71911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  /// Type throwing via limit condition.
72011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  struct throw_value_limit : public throw_value_base<limit_condition>
72111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  {
72211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    typedef throw_value_base<limit_condition> base_type;
72311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
72411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifndef _GLIBCXX_IS_AGGREGATE
72511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    throw_value_limit() { }
72611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
72711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    throw_value_limit(const throw_value_limit& __other)
72811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    : base_type(__other._M_i) { }
72911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
73011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if __cplusplus >= 201103L
73111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    throw_value_limit(throw_value_limit&&) = default;
73211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
73311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
73411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    explicit throw_value_limit(const std::size_t __i) : base_type(__i) { }
73511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
73611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
73711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    throw_value_limit&
73811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    operator=(const throw_value_limit& __other)
73911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
74011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      base_type::operator=(__other);
74111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      return *this;
74211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
74311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
74411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if __cplusplus >= 201103L
74511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    throw_value_limit&
74611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    operator=(throw_value_limit&&) = default;
74711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
74811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  };
74911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
75011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  /// Type throwing via random condition.
75111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  struct throw_value_random : public throw_value_base<random_condition>
75211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  {
75311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    typedef throw_value_base<random_condition> base_type;
75411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
75511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#ifndef _GLIBCXX_IS_AGGREGATE
75611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    throw_value_random() { }
75711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
75811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    throw_value_random(const throw_value_random& __other)
75911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    : base_type(__other._M_i) { }
76011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
76111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if __cplusplus >= 201103L
76211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    throw_value_random(throw_value_random&&) = default;
76311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
76411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
76511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    explicit throw_value_random(const std::size_t __i) : base_type(__i) { }
76611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
76711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
76811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    throw_value_random&
76911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    operator=(const throw_value_random& __other)
77011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
77111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      base_type::operator=(__other);
77211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      return *this;
77311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    }
77411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
77511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if __cplusplus >= 201103L
77611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    throw_value_random&
77711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    operator=(throw_value_random&&) = default;
77811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
77911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  };
78011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
78111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
78211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  /**
78311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert   *  @brief Allocator class with logging and exception generation control.
78411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert   * Intended to be used as an allocator_type in templatized code.
78511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert   *  @ingroup allocators
78611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert   *
78711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert   *  Note: Deallocate not allowed to throw.
78811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert   */
78911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  template<typename _Tp, typename _Cond>
79011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    class throw_allocator_base
79111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    : public annotate_base, public _Cond
79211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
79311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    public:
79411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      typedef size_t 				size_type;
79511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      typedef ptrdiff_t 			difference_type;
79611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      typedef _Tp 				value_type;
79711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      typedef value_type* 			pointer;
79811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      typedef const value_type* 		const_pointer;
79911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      typedef value_type& 			reference;
80011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      typedef const value_type& 		const_reference;
80111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
80211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if __cplusplus >= 201103L
80311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      // _GLIBCXX_RESOLVE_LIB_DEFECTS
80411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      // 2103. std::allocator propagate_on_container_move_assignment
80511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      typedef std::true_type propagate_on_container_move_assignment;
80611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
80711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
80811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    private:
80911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      typedef _Cond				condition_type;
81011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
81111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      std::allocator<value_type> 		_M_allocator;
81211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
81311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      using condition_type::throw_conditionally;
81411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
81511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    public:
81611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      size_type
81711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      max_size() const _GLIBCXX_USE_NOEXCEPT
81811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      { return _M_allocator.max_size(); }
81911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
82011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      pointer
82111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      address(reference __x) const _GLIBCXX_NOEXCEPT
82211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      { return std::__addressof(__x); }
82311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
82411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      const_pointer
82511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      address(const_reference __x) const _GLIBCXX_NOEXCEPT
82611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      { return std::__addressof(__x); }
82711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
82811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      pointer
82911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      allocate(size_type __n, std::allocator<void>::const_pointer hint = 0)
83011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      {
83111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	if (__n > this->max_size())
83211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  std::__throw_bad_alloc();
83311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
83411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	throw_conditionally();
83511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	pointer const a = _M_allocator.allocate(__n, hint);
83611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	insert(a, sizeof(value_type) * __n);
83711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	return a;
83811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      }
83911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
84011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if __cplusplus >= 201103L
84111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      template<typename _Up, typename... _Args>
84211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        void
84311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        construct(_Up* __p, _Args&&... __args)
84411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	{
84511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  _M_allocator.construct(__p, std::forward<_Args>(__args)...);
84611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  insert_construct(__p);
84711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
84811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
84911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      template<typename _Up>
85011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        void
85111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        destroy(_Up* __p)
85211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert        {
85311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  erase_construct(__p);
85411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	  _M_allocator.destroy(__p);
85511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	}
85611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#else
85711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      void
85811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      construct(pointer __p, const value_type& val)
85911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      { return _M_allocator.construct(__p, val); }
86011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
86111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      void
86211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      destroy(pointer __p)
86311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      { _M_allocator.destroy(__p); }
86411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
86511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
86611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      void
86711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      deallocate(pointer __p, size_type __n)
86811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      {
86911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	erase(__p, sizeof(value_type) * __n);
87011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	_M_allocator.deallocate(__p, __n);
87111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      }
87211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
87311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      void
87411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      check_allocated(pointer __p, size_type __n)
87511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      {
87611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	size_type __t = sizeof(value_type) * __n;
87711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	annotate_base::check_allocated(__p, __t);
87811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      }
87911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
88011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      void
88111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      check(size_type __n)
88211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      { annotate_base::check(__n); }
88311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  };
88411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
88511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  template<typename _Tp, typename _Cond>
88611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    inline bool
88711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    operator==(const throw_allocator_base<_Tp, _Cond>&,
88811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	       const throw_allocator_base<_Tp, _Cond>&)
88911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    { return true; }
89011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
89111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  template<typename _Tp, typename _Cond>
89211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    inline bool
89311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    operator!=(const throw_allocator_base<_Tp, _Cond>&,
89411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	       const throw_allocator_base<_Tp, _Cond>&)
89511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    { return false; }
89611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
89711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  /// Allocator throwing via limit condition.
89811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  template<typename _Tp>
89911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    struct throw_allocator_limit
90011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    : public throw_allocator_base<_Tp, limit_condition>
90111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
90211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      template<typename _Tp1>
90311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	struct rebind
90411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	{ typedef throw_allocator_limit<_Tp1> other; };
90511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
90611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      throw_allocator_limit() _GLIBCXX_USE_NOEXCEPT { }
90711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
90811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      throw_allocator_limit(const throw_allocator_limit&)
90911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _GLIBCXX_USE_NOEXCEPT { }
91011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
91111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      template<typename _Tp1>
91211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	throw_allocator_limit(const throw_allocator_limit<_Tp1>&)
91311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	_GLIBCXX_USE_NOEXCEPT { }
91411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
91511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      ~throw_allocator_limit() _GLIBCXX_USE_NOEXCEPT { }
91611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    };
91711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
91811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  /// Allocator throwing via random condition.
91911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  template<typename _Tp>
92011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    struct throw_allocator_random
92111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    : public throw_allocator_base<_Tp, random_condition>
92211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
92311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      template<typename _Tp1>
92411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	struct rebind
92511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	{ typedef throw_allocator_random<_Tp1> other; };
92611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
92711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      throw_allocator_random() _GLIBCXX_USE_NOEXCEPT { }
92811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
92911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      throw_allocator_random(const throw_allocator_random&)
93011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      _GLIBCXX_USE_NOEXCEPT { }
93111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
93211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      template<typename _Tp1>
93311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	throw_allocator_random(const throw_allocator_random<_Tp1>&)
93411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	_GLIBCXX_USE_NOEXCEPT { }
93511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
93611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      ~throw_allocator_random() _GLIBCXX_USE_NOEXCEPT { }
93711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    };
93811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
93911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert_GLIBCXX_END_NAMESPACE_VERSION
94011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} // namespace
94111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
94211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#if __cplusplus >= 201103L
94311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
94411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert# include <bits/functional_hash.h>
94511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
94611cd02dfb91661c65134cac258cf5924270e9d2Dan Albertnamespace std _GLIBCXX_VISIBILITY(default)
94711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert{
94811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  /// Explicit specialization of std::hash for __gnu_cxx::throw_value_limit.
94911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  template<>
95011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    struct hash<__gnu_cxx::throw_value_limit>
95111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    : public std::unary_function<__gnu_cxx::throw_value_limit, size_t>
95211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
95311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      size_t
95411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      operator()(const __gnu_cxx::throw_value_limit& __val) const
95511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      {
95611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	__gnu_cxx::throw_value_limit::throw_conditionally();
95711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	std::hash<std::size_t> __h;
95811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	size_t __result = __h(__val._M_i);
95911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	return __result;
96011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      }
96111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    };
96211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
96311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  /// Explicit specialization of std::hash for __gnu_cxx::throw_value_random.
96411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert  template<>
96511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    struct hash<__gnu_cxx::throw_value_random>
96611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    : public std::unary_function<__gnu_cxx::throw_value_random, size_t>
96711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    {
96811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      size_t
96911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      operator()(const __gnu_cxx::throw_value_random& __val) const
97011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      {
97111cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	__gnu_cxx::throw_value_random::throw_conditionally();
97211cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	std::hash<std::size_t> __h;
97311cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	size_t __result = __h(__val._M_i);
97411cd02dfb91661c65134cac258cf5924270e9d2Dan Albert	return __result;
97511cd02dfb91661c65134cac258cf5924270e9d2Dan Albert      }
97611cd02dfb91661c65134cac258cf5924270e9d2Dan Albert    };
97711cd02dfb91661c65134cac258cf5924270e9d2Dan Albert} // end namespace std
97811cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
97911cd02dfb91661c65134cac258cf5924270e9d2Dan Albert
98011cd02dfb91661c65134cac258cf5924270e9d2Dan Albert#endif
981