]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - libstdc++-v3/include/ext/throw_allocator.h
Update copyright years in libstdc++-v3/
[thirdparty/gcc.git] / libstdc++-v3 / include / ext / throw_allocator.h
index 8942232c825c1014101a44801d7cd5f1bd1d195b..30b6c47d503c9bd89ad9728c505afbd88cede675 100644 (file)
@@ -1,6 +1,6 @@
 // -*- 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
@@ -55,7 +55,7 @@
 #include <utility>
 #include <bits/functexcept.h>
 #include <bits/move.h>
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#if __cplusplus >= 201103L
 # include <functional>
 # include <random>
 #else
@@ -77,14 +77,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   // 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
@@ -97,7 +90,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     annotate_base()
     {
       label();
-      map();
+      map_alloc();
     }
 
     static void
@@ -118,8 +111,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
          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));
@@ -127,22 +120,52 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
          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");
@@ -162,32 +185,121 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 
     // 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&);
@@ -196,8 +308,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     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');
@@ -217,6 +329,24 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       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()
     {
@@ -224,12 +354,21 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       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&
@@ -237,10 +376,20 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
   {
     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;
   }
 
@@ -392,7 +541,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     { 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
@@ -403,7 +552,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     static double
     generate()
     {
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#if __cplusplus >= 201103L
       const distribution_type distribution(0, 1);
       static auto generator = std::bind(distribution, engine());
 #else
@@ -466,7 +615,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       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
@@ -483,7 +632,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        return *this;
       }
 
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#if __cplusplus >= 201103L
       // Shall not throw.
       throw_value_base&
       operator=(throw_value_base&&) = default;
@@ -578,7 +727,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     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
 
@@ -592,7 +741,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       return *this;
     }
 
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#if __cplusplus >= 201103L
     throw_value_limit&
     operator=(throw_value_limit&&) = default;
 #endif
@@ -609,7 +758,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
     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
 
@@ -623,7 +772,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       return *this;
     }
 
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#if __cplusplus >= 201103L
     throw_value_random&
     operator=(throw_value_random&&) = default;
 #endif
@@ -650,6 +799,12 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       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;
 
@@ -682,16 +837,22 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
        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)
@@ -717,8 +878,8 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
       }
 
       void
-      check_allocated(size_type __n)
-      { annotate_base::check_allocated(__n); }
+      check(size_type __n)
+      { annotate_base::check(__n); }
   };
 
   template<typename _Tp, typename _Cond>
@@ -778,7 +939,7 @@ _GLIBCXX_BEGIN_NAMESPACE_VERSION
 _GLIBCXX_END_NAMESPACE_VERSION
 } // namespace
 
-#ifdef __GXX_EXPERIMENTAL_CXX0X__
+#if __cplusplus >= 201103L
 
 # include <bits/functional_hash.h>
 
@@ -792,13 +953,14 @@ namespace std _GLIBCXX_VISIBILITY(default)
       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>
@@ -806,6 +968,7 @@ namespace std _GLIBCXX_VISIBILITY(default)
       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;