// -*- C++ -*-
-// Copyright (C) 2005-2012 Free Software Foundation, Inc.
+// Copyright (C) 2005-2014 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the terms
#include <utility>
#include <bits/functexcept.h>
#include <bits/move.h>
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#if __cplusplus >= 201103L
# include <functional>
# include <random>
#else
// Substitute for forced_error object when -fno-exceptions.
inline void
__throw_forced_error()
- {
-#if __EXCEPTIONS
- throw forced_error();
-#else
- __builtin_abort();
-#endif
- }
-
+ { _GLIBCXX_THROW_OR_ABORT(forced_error()); }
/**
* @brief Base class for checking address and label information
annotate_base()
{
label();
- map();
+ map_alloc();
}
static void
std::__throw_logic_error(error.c_str());
}
- const_iterator found = map().find(p);
- if (found != map().end())
+ const_iterator found = map_alloc().find(p);
+ if (found != map_alloc().end())
{
std::string error("annotate_base::insert double insert!\n");
log_to_string(error, make_entry(p, size));
std::__throw_logic_error(error.c_str());
}
- map().insert(make_entry(p, size));
+ map_alloc().insert(make_entry(p, size));
}
void
erase(void* p, size_t size)
{
check_allocated(p, size);
- map().erase(p);
+ map_alloc().erase(p);
+ }
+
+#if __cplusplus >= 201103L
+ void
+ insert_construct(void* p)
+ {
+ if (!p)
+ {
+ std::string error("annotate_base::insert_construct null!\n");
+ std::__throw_logic_error(error.c_str());
+ }
+
+ auto found = map_construct().find(p);
+ if (found != map_construct().end())
+ {
+ std::string error("annotate_base::insert_construct double insert!\n");
+ log_to_string(error, std::make_pair(p, get_label()));
+ log_to_string(error, *found);
+ std::__throw_logic_error(error.c_str());
+ }
+
+ map_construct().insert(std::make_pair(p, get_label()));
}
+ void
+ erase_construct(void* p)
+ {
+ check_constructed(p);
+ map_construct().erase(p);
+ }
+#endif
+
// See if a particular address and allocation size has been saved.
inline void
check_allocated(void* p, size_t size)
{
- const_iterator found = map().find(p);
- if (found == map().end())
+ const_iterator found = map_alloc().find(p);
+ if (found == map_alloc().end())
{
std::string error("annotate_base::check_allocated by value "
"null erase!\n");
// See if a given label has been allocated.
inline void
- check_allocated(size_t label)
+ check(size_t label)
{
- const_iterator beg = map().begin();
- const_iterator end = map().end();
+ std::string found;
+ {
+ const_iterator beg = map_alloc().begin();
+ const_iterator end = map_alloc().end();
+ while (beg != end)
+ {
+ if (beg->second.first == label)
+ log_to_string(found, *beg);
+ ++beg;
+ }
+ }
+
+#if __cplusplus >= 201103L
+ {
+ auto beg = map_construct().begin();
+ auto end = map_construct().end();
+ while (beg != end)
+ {
+ if (beg->second == label)
+ log_to_string(found, *beg);
+ ++beg;
+ }
+ }
+#endif
+
+ if (!found.empty())
+ {
+ std::string error("annotate_base::check by label\n");
+ error += found;
+ std::__throw_logic_error(error.c_str());
+ }
+ }
+
+ // See if there is anything left allocated or constructed.
+ inline static void
+ check()
+ {
+ std::string found;
+ {
+ const_iterator beg = map_alloc().begin();
+ const_iterator end = map_alloc().end();
+ while (beg != end)
+ {
+ log_to_string(found, *beg);
+ ++beg;
+ }
+ }
+
+#if __cplusplus >= 201103L
+ {
+ auto beg = map_construct().begin();
+ auto end = map_construct().end();
+ while (beg != end)
+ {
+ log_to_string(found, *beg);
+ ++beg;
+ }
+ }
+#endif
+
+ if (!found.empty())
+ {
+ std::string error("annotate_base::check \n");
+ error += found;
+ std::__throw_logic_error(error.c_str());
+ }
+ }
+
+#if __cplusplus >= 201103L
+ inline void
+ check_constructed(void* p)
+ {
+ auto found = map_construct().find(p);
+ if (found == map_construct().end())
+ {
+ std::string error("annotate_base::check_constructed not "
+ "constructed!\n");
+ log_to_string(error, std::make_pair(p, get_label()));
+ std::__throw_logic_error(error.c_str());
+ }
+ }
+
+ inline void
+ check_constructed(size_t label)
+ {
+ auto beg = map_construct().begin();
+ auto end = map_construct().end();
std::string found;
while (beg != end)
{
- if (beg->second.first == label)
+ if (beg->second == label)
log_to_string(found, *beg);
++beg;
}
if (!found.empty())
{
- std::string error("annotate_base::check_allocated by label\n");
+ std::string error("annotate_base::check_constructed by label\n");
error += found;
std::__throw_logic_error(error.c_str());
}
}
+#endif
private:
- typedef std::pair<size_t, size_t> data_type;
- typedef std::map<void*, data_type> map_type;
- typedef map_type::value_type entry_type;
- typedef map_type::const_iterator const_iterator;
- typedef map_type::const_reference const_reference;
+ typedef std::pair<size_t, size_t> data_type;
+ typedef std::map<void*, data_type> map_alloc_type;
+ typedef map_alloc_type::value_type entry_type;
+ typedef map_alloc_type::const_iterator const_iterator;
+ typedef map_alloc_type::const_reference const_reference;
+#if __cplusplus >= 201103L
+ typedef std::map<void*, size_t> map_construct_type;
+#endif
friend std::ostream&
operator<<(std::ostream&, const annotate_base&);
make_entry(void* p, size_t size)
{ return std::make_pair(p, data_type(get_label(), size)); }
- void
- log_to_string(std::string& s, const_reference ref) const
+ static void
+ log_to_string(std::string& s, const_reference ref)
{
char buf[40];
const char tab('\t');
s += '\n';
}
+#if __cplusplus >= 201103L
+ static void
+ log_to_string(std::string& s, const std::pair<const void*, size_t>& ref)
+ {
+ char buf[40];
+ const char tab('\t');
+ s += "label: ";
+ unsigned long l = static_cast<unsigned long>(ref.second);
+ __builtin_sprintf(buf, "%lu", l);
+ s += buf;
+ s += tab;
+ s += "address: ";
+ __builtin_sprintf(buf, "%p", ref.first);
+ s += buf;
+ s += '\n';
+ }
+#endif
+
static size_t&
label()
{
return _S_label;
}
- static map_type&
- map()
+ static map_alloc_type&
+ map_alloc()
+ {
+ static map_alloc_type _S_map;
+ return _S_map;
+ }
+
+#if __cplusplus >= 201103L
+ static map_construct_type&
+ map_construct()
{
- static map_type _S_map;
+ static map_construct_type _S_map;
return _S_map;
}
+#endif
};
inline std::ostream&
{
std::string error;
typedef annotate_base base_type;
- base_type::const_iterator beg = __b.map().begin();
- base_type::const_iterator end = __b.map().end();
- for (; beg != end; ++beg)
- __b.log_to_string(error, *beg);
+ {
+ base_type::const_iterator beg = __b.map_alloc().begin();
+ base_type::const_iterator end = __b.map_alloc().end();
+ for (; beg != end; ++beg)
+ __b.log_to_string(error, *beg);
+ }
+#if __cplusplus >= 201103L
+ {
+ auto beg = __b.map_construct().begin();
+ auto end = __b.map_construct().end();
+ for (; beg != end; ++beg)
+ __b.log_to_string(error, *beg);
+ }
+#endif
return os << error;
}
{ engine().seed(__s); }
private:
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#if __cplusplus >= 201103L
typedef std::uniform_real_distribution<double> distribution_type;
typedef std::mt19937 engine_type;
#else
static double
generate()
{
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#if __cplusplus >= 201103L
const distribution_type distribution(0, 1);
static auto generator = std::bind(distribution, engine());
#else
throw_value_base(const throw_value_base& __v) : _M_i(__v._M_i)
{ throw_conditionally(); }
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#if __cplusplus >= 201103L
// Shall not throw.
throw_value_base(throw_value_base&&) = default;
#endif
return *this;
}
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#if __cplusplus >= 201103L
// Shall not throw.
throw_value_base&
operator=(throw_value_base&&) = default;
throw_value_limit(const throw_value_limit& __other)
: base_type(__other._M_i) { }
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#if __cplusplus >= 201103L
throw_value_limit(throw_value_limit&&) = default;
#endif
return *this;
}
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#if __cplusplus >= 201103L
throw_value_limit&
operator=(throw_value_limit&&) = default;
#endif
throw_value_random(const throw_value_random& __other)
: base_type(__other._M_i) { }
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#if __cplusplus >= 201103L
throw_value_random(throw_value_random&&) = default;
#endif
return *this;
}
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#if __cplusplus >= 201103L
throw_value_random&
operator=(throw_value_random&&) = default;
#endif
typedef value_type& reference;
typedef const value_type& const_reference;
+#if __cplusplus >= 201103L
+ // _GLIBCXX_RESOLVE_LIB_DEFECTS
+ // 2103. std::allocator propagate_on_container_move_assignment
+ typedef std::true_type propagate_on_container_move_assignment;
+#endif
+
private:
typedef _Cond condition_type;
return a;
}
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#if __cplusplus >= 201103L
template<typename _Up, typename... _Args>
void
construct(_Up* __p, _Args&&... __args)
- { return _M_allocator.construct(__p, std::forward<_Args>(__args)...); }
+ {
+ _M_allocator.construct(__p, std::forward<_Args>(__args)...);
+ insert_construct(__p);
+ }
template<typename _Up>
void
destroy(_Up* __p)
- { _M_allocator.destroy(__p); }
+ {
+ erase_construct(__p);
+ _M_allocator.destroy(__p);
+ }
#else
void
construct(pointer __p, const value_type& val)
}
void
- check_allocated(size_type __n)
- { annotate_base::check_allocated(__n); }
+ check(size_type __n)
+ { annotate_base::check(__n); }
};
template<typename _Tp, typename _Cond>
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#if __cplusplus >= 201103L
# include <bits/functional_hash.h>
size_t
operator()(const __gnu_cxx::throw_value_limit& __val) const
{
+ __gnu_cxx::throw_value_limit::throw_conditionally();
std::hash<std::size_t> __h;
size_t __result = __h(__val._M_i);
return __result;
}
};
- /// Explicit specialization of std::hash for __gnu_cxx::throw_value_limit.
+ /// Explicit specialization of std::hash for __gnu_cxx::throw_value_random.
template<>
struct hash<__gnu_cxx::throw_value_random>
: public std::unary_function<__gnu_cxx::throw_value_random, size_t>
size_t
operator()(const __gnu_cxx::throw_value_random& __val) const
{
+ __gnu_cxx::throw_value_random::throw_conditionally();
std::hash<std::size_t> __h;
size_t __result = __h(__val._M_i);
return __result;