Index: include/std/utility =================================================================== --- include/std/utility (revision 136999) +++ include/std/utility (working copy) @@ -1,6 +1,6 @@ // -*- C++ -*- -// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 +// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 // Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free @@ -84,7 +84,7 @@ # undef _GLIBCXX_BEGIN_NAMESPACE_TR1 # undef _GLIBCXX_INCLUDE_AS_CXX0X # endif -# include +# include #endif #endif /* _GLIBCXX_UTILITY */ Index: include/std/memory =================================================================== --- include/std/memory (revision 136999) +++ include/std/memory (working copy) @@ -1,6 +1,6 @@ // -*- C++ -*- -// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 +// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 // Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free @@ -69,6 +69,7 @@ # include # include # include // std::less +# include # include # include # if _GLIBCXX_DEPRECATED Index: include/ext/vstring_util.h =================================================================== --- include/ext/vstring_util.h (revision 136999) +++ include/ext/vstring_util.h (working copy) @@ -1,6 +1,6 @@ // Versatile string utility -*- C++ -*- -// Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc. +// Copyright (C) 2005, 2006, 2007, 2008 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 @@ -46,7 +46,7 @@ #include #include #include -#include +#include _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) Index: include/ext/throw_allocator.h =================================================================== --- include/ext/throw_allocator.h (revision 136999) +++ include/ext/throw_allocator.h (working copy) @@ -1,6 +1,6 @@ // -*- C++ -*- -// Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc. +// Copyright (C) 2005, 2006, 2007, 2008 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 @@ -60,7 +60,7 @@ #include #include #include -#include +#include _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) Index: include/ext/pool_allocator.h =================================================================== --- include/ext/pool_allocator.h (revision 136999) +++ include/ext/pool_allocator.h (working copy) @@ -54,7 +54,7 @@ #include #include #include -#include +#include _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) Index: include/ext/bitmap_allocator.h =================================================================== --- include/ext/bitmap_allocator.h (revision 136999) +++ include/ext/bitmap_allocator.h (working copy) @@ -1,6 +1,6 @@ // Bitmap Allocator. -*- C++ -*- -// Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation, Inc. +// Copyright (C) 2004, 2005, 2006, 2007, 2008 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 @@ -41,7 +41,7 @@ #include // For operator new. #include // _GLIBCXX_DEBUG_ASSERT #include -#include +#include /** @brief The constant in the expression below is the alignment * required in bytes. Index: include/ext/new_allocator.h =================================================================== --- include/ext/new_allocator.h (revision 136999) +++ include/ext/new_allocator.h (working copy) @@ -36,7 +36,7 @@ #include #include -#include +#include _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) Index: include/ext/malloc_allocator.h =================================================================== --- include/ext/malloc_allocator.h (revision 136999) +++ include/ext/malloc_allocator.h (working copy) @@ -1,6 +1,6 @@ // Allocator that wraps "C" malloc -*- C++ -*- -// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 +// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 // Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free @@ -38,7 +38,7 @@ #include #include #include -#include +#include _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) Index: include/ext/array_allocator.h =================================================================== --- include/ext/array_allocator.h (revision 136999) +++ include/ext/array_allocator.h (working copy) @@ -1,6 +1,6 @@ // array allocator -*- C++ -*- -// Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation, Inc. +// Copyright (C) 2004, 2005, 2006, 2007, 2008 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 @@ -38,7 +38,7 @@ #include #include #include -#include +#include _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) Index: include/ext/mt_allocator.h =================================================================== --- include/ext/mt_allocator.h (revision 136999) +++ include/ext/mt_allocator.h (working copy) @@ -1,6 +1,7 @@ // MT-optimized allocator -*- C++ -*- -// Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc. +// Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 +// 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 @@ -38,7 +39,7 @@ #include #include #include -#include +#include _GLIBCXX_BEGIN_NAMESPACE(__gnu_cxx) Index: include/bits/stl_algobase.h =================================================================== --- include/bits/stl_algobase.h (revision 136999) +++ include/bits/stl_algobase.h (working copy) @@ -74,7 +74,7 @@ #include #include #include -#include // For std::swap and _GLIBCXX_MOVE +#include // For std::swap and _GLIBCXX_MOVE _GLIBCXX_BEGIN_NAMESPACE(std) Index: include/bits/unique_ptr.h =================================================================== --- include/bits/unique_ptr.h (revision 0) +++ include/bits/unique_ptr.h (revision 0) @@ -0,0 +1,447 @@ +// unique_ptr implementation -*- C++ -*- + +// Copyright (C) 2008 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 of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +// As a special exception, you may use this file as part of a free software +// library without restriction. Specifically, if other files instantiate +// templates or use macros or inline functions from this file, or you compile +// this file and link it with other files to produce an executable, this +// file does not by itself cause the resulting executable to be covered by +// the GNU General Public License. This exception does not however +// invalidate any other reasons why the executable file might be covered by +// the GNU General Public License. + +/** @file unique_ptr.h + * This is an internal header file, included by other library headers. + * You should not attempt to use it directly. + */ + +#ifndef _UNIQUE_PTR_H +#define _UNIQUE_PTR_H 1 + +#ifndef __GXX_EXPERIMENTAL_CXX0X__ +# include +#endif + +#include +#include +#include +#include +#include + +_GLIBCXX_BEGIN_NAMESPACE(std) + + template + struct default_delete + { + default_delete() { } + + template + default_delete(const default_delete<_Up>&) { } + + void + operator()(_Tp* __ptr) const + { + static_assert(sizeof(_Tp)>0, + "can't delete pointer to incomplete type"); + delete __ptr; + } + }; + + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR 740 - omit specialization for array objects with a compile time length + template + struct default_delete<_Tp[]> + { + void + operator()(_Tp* __ptr) const + { + static_assert(sizeof(_Tp)>0, + "can't delete pointer to incomplete type"); + delete [] __ptr; + } + }; + + template > + class unique_ptr + { + typedef _Tp* pointer; + typedef unique_ptr<_Tp, _Tp_Deleter> __this_type; + typedef std::tuple __tuple_type; + typedef __tuple_type __this_type::* __unspecified_bool_type; + typedef pointer __this_type::* __unspecified_pointer_type; + + public: + typedef _Tp element_type; + typedef _Tp_Deleter deleter_type; + + // constructors + unique_ptr() + : _M_t(pointer(), deleter_type()) + { static_assert(!std::is_pointer::value, + "constructed with null function pointer deleter"); } + + explicit + unique_ptr(pointer __p) + : _M_t(__p, deleter_type()) + { static_assert(!std::is_pointer::value, + "constructed with null function pointer deleter"); } + + unique_ptr(pointer __p, + typename std::conditional::value, + deleter_type, const deleter_type&>::type __d) + : _M_t(__p, __d) { } + + unique_ptr(pointer __p, + typename std::remove_reference::type&& __d) + : _M_t(std::move(__p), std::move(__d)) + { static_assert(!std::is_reference::value, + "rvalue deleter bound to reference"); } + + // move constructors + unique_ptr(unique_ptr && __u) + : _M_t(__u.release(), std::forward(__u.get_deleter())) { } + + template + unique_ptr(unique_ptr<_Up, _Up_Deleter>&& __u) + : _M_t(__u.release(), std::forward(__u.get_deleter())) + { } + + // destructor + ~unique_ptr() { reset(); } + + // assignment + unique_ptr& + operator=(unique_ptr&& __u) + { + reset(__u.release()); + get_deleter() = std::move(__u.get_deleter()); + return *this; + } + + template + unique_ptr& + operator=(unique_ptr<_Up, _Up_Deleter>&& __u) + { + reset(__u.release()); + get_deleter() = std::move(__u.get_deleter()); + return *this; + } + + unique_ptr& + operator=(__unspecified_pointer_type) + { + reset(); + return *this; + } + + // observers + typename std::add_lvalue_reference::type operator*() const + { + _GLIBCXX_DEBUG_ASSERT(get() != 0); + return *get(); + } + + pointer + operator->() const + { + _GLIBCXX_DEBUG_ASSERT(get() != 0); + return get(); + } + + pointer + get() const + { return std::get<0>(_M_t); } + + typename std::add_lvalue_reference::type + get_deleter() + { return std::get<1>(_M_t); } + + typename std::add_lvalue_reference< + typename std::add_const::type + >::type + get_deleter() const + { return std::get<1>(_M_t); } + + operator __unspecified_bool_type () const + { return get() == 0 ? 0 : &__this_type::_M_t; } + + // modifiers + pointer + release() + { + pointer __p = get(); + std::get<0>(_M_t) = 0; + return __p; + } + + void + reset(pointer __p = 0) + { + if (__p != get()) + { + get_deleter()(get()); + std::get<0>(_M_t) = __p; + } + } + + void + swap(unique_ptr&& __u) + { using std::swap; + swap(_M_t, __u._M_t); + } + + private: + // disable copy from lvalue + unique_ptr(const unique_ptr&); + + template + unique_ptr(const unique_ptr<_Up, _Up_Deleter>&); + + // disable assignment from lvalue + unique_ptr& operator=(const unique_ptr&); + + template + unique_ptr& operator=(const unique_ptr<_Up, _Up_Deleter>&); + + private: + __tuple_type _M_t; + }; + + // 20.6.11.3 unique_ptr for array objects with a runtime length + // [unique.ptr.runtime] + // _GLIBCXX_RESOLVE_LIB_DEFECTS + // DR 740 - omit specialization for array objects with a compile time length + template + class unique_ptr<_Tp[], _Tp_Deleter> + { + typedef _Tp* pointer; + typedef unique_ptr<_Tp[], _Tp_Deleter> __this_type; + typedef std::tuple __tuple_type; + typedef __tuple_type __this_type::* __unspecified_bool_type; + typedef pointer __this_type::* __unspecified_pointer_type; + public: + typedef _Tp element_type; + typedef _Tp_Deleter deleter_type; + + // constructors + unique_ptr() + : _M_t(pointer(), deleter_type()) + { static_assert(!std::is_pointer::value, + "constructed with null function pointer deleter"); } + + explicit + unique_ptr(pointer __p) + : _M_t(__p, deleter_type()) + { static_assert(!std::is_pointer::value, + "constructed with null function pointer deleter"); } + + unique_ptr(pointer __p, + typename std::conditional::value, + deleter_type, const deleter_type&>::type __d) + : _M_t(__p, __d) { } + + unique_ptr(pointer __p, + typename std::remove_reference::type && __d) + : _M_t(std::move(__p), std::move(__d)) + { static_assert(!std::is_reference::value, + "rvalue deleter bound to reference"); } + + // move constructors + unique_ptr(unique_ptr&& __u) + : _M_t(__u.release(), std::forward(__u.get_deleter())) { } + + template + unique_ptr(unique_ptr<_Up, _Up_Deleter>&& __u) + : _M_t(__u.release(), std::forward(__u.get_deleter())) + { } + + // destructor + ~unique_ptr() { reset(); } + + // assignment + unique_ptr& + operator=(unique_ptr&& __u) + { + reset(__u.release()); + get_deleter() = std::move(__u.get_deleter()); + return *this; + } + + template + unique_ptr& + operator=(unique_ptr<_Up, _Up_Deleter>&& __u) + { + reset(__u.release()); + get_deleter() = std::move(__u.get_deleter()); + return *this; + } + + unique_ptr& + operator=(__unspecified_pointer_type) + { + reset(); + return *this; + } + + // observers + typename std::add_lvalue_reference::type + operator[](size_t __i) const + { + _GLIBCXX_DEBUG_ASSERT(get() != 0); + return get()[__i]; + } + + pointer + get() const + { return std::get<0>(_M_t); } + + typename std::add_lvalue_reference::type + get_deleter() + { return std::get<1>(_M_t); } + + typename std::add_lvalue_reference< + typename std::add_const::type + >::type + get_deleter() const + { return std::get<1>(_M_t); } + + operator __unspecified_bool_type () const + { return get() == 0 ? 0 : &__this_type::_M_t; } + + // modifiers + pointer + release() + { + pointer __p = get(); + std::get<0>(_M_t) = 0; + return __p; + } + + void + reset(pointer __p = 0) + { + if (__p != get()) + { + get_deleter()(get()); + std::get<0>(_M_t) = __p; + } + } + + void + swap(unique_ptr&& __u) + { + using std::swap; + swap(_M_t, __u._M_t); + } + + private: + // disable copy from lvalue + unique_ptr(const unique_ptr&); + unique_ptr& operator=(const unique_ptr&); + + // disable construction from convertible pointer types + // (N2315 - 20.6.5.3.1) + template unique_ptr(_Up*, + typename std::conditional::value, + deleter_type, const deleter_type&>::type, + typename std::enable_if::value>::type* = 0); + + template unique_ptr(_Up*, + typename std::remove_reference::type&&, + typename std::enable_if::value>::type* = 0); + + template explicit unique_ptr(_Up*, + typename std::enable_if::value>::type* = 0); + + // disable reset with convertible pointer types (N2315 - 20.6.5.3.3) + template + typename std::enable_if::value>::type reset(_Up*); + + private: + __tuple_type _M_t; + }; + + template + inline void + swap(unique_ptr<_Tp, _Tp_Deleter>& __x, + unique_ptr<_Tp, _Tp_Deleter>& __y) + { __x.swap(__y); } + + template + inline void + swap(unique_ptr<_Tp, _Tp_Deleter>&& __x, + unique_ptr<_Tp, _Tp_Deleter>& __y) + { __x.swap(__y); } + + template + inline void + swap(unique_ptr<_Tp, _Tp_Deleter>& __x, + unique_ptr<_Tp, _Tp_Deleter>&& __y) + { __x.swap(__y); } + + template + inline bool + operator==(const unique_ptr<_Tp, _Tp_Deleter>& __x, + const unique_ptr<_Up, _Up_Deleter>& __y) + { return __x.get() == __y.get(); } + + template + inline bool + operator!=(const unique_ptr<_Tp, _Tp_Deleter>& __x, + const unique_ptr<_Up, _Up_Deleter>& __y) + { return !(__x.get() == __y.get()); } + + template + inline bool + operator<(const unique_ptr<_Tp, _Tp_Deleter>& __x, + const unique_ptr<_Up, _Up_Deleter>& __y) + { return __x.get() < __y.get(); } + + template + inline bool + operator<=(const unique_ptr<_Tp, _Tp_Deleter>& __x, + const unique_ptr<_Up, _Up_Deleter>& __y) + { return !(__y.get() < __x.get()); } + + template + inline bool + operator>(const unique_ptr<_Tp, _Tp_Deleter>& __x, + const unique_ptr<_Up, _Up_Deleter>& __y) + { return __y.get() < __x.get(); } + + template + inline bool + operator>=(const unique_ptr<_Tp, _Tp_Deleter>& __x, + const unique_ptr<_Up, _Up_Deleter>& __y) + { return !(__x.get() < __y.get()); } + +_GLIBCXX_END_NAMESPACE + +#endif /* _UNIQUE_PTR_H */ Index: include/bits/stl_heap.h =================================================================== --- include/bits/stl_heap.h (revision 136999) +++ include/bits/stl_heap.h (working copy) @@ -62,7 +62,7 @@ #define _STL_HEAP_H 1 #include -#include +#include _GLIBCXX_BEGIN_NAMESPACE(std) Index: include/bits/stl_pair.h =================================================================== --- include/bits/stl_pair.h (revision 136999) +++ include/bits/stl_pair.h (working copy) @@ -1,6 +1,6 @@ // Pair implementation -*- C++ -*- -// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007 +// Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008 // Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free @@ -62,8 +62,8 @@ #ifndef _STL_PAIR_H #define _STL_PAIR_H 1 -#include // for std::move / std::forward, std::decay, and - // std::swap +#include // for std::move / std::forward, std::decay, and + // std::swap _GLIBCXX_BEGIN_NAMESPACE(std) Index: include/bits/stl_iterator.h =================================================================== --- include/bits/stl_iterator.h (revision 136999) +++ include/bits/stl_iterator.h (working copy) @@ -68,7 +68,7 @@ #include #include -#include +#include _GLIBCXX_BEGIN_NAMESPACE(std) Index: include/Makefile.am =================================================================== --- include/Makefile.am (revision 136999) +++ include/Makefile.am (working copy) @@ -104,6 +104,7 @@ ${bits_srcdir}/locale_facets_nonio.tcc \ ${bits_srcdir}/localefwd.h \ ${bits_srcdir}/mask_array.h \ + ${bits_srcdir}/move.h \ ${bits_srcdir}/ostream.tcc \ ${bits_srcdir}/ostream_insert.h \ ${bits_srcdir}/postypes.h \ @@ -123,7 +124,6 @@ ${bits_srcdir}/stl_iterator_base_types.h \ ${bits_srcdir}/stl_list.h \ ${bits_srcdir}/stl_map.h \ - ${bits_srcdir}/stl_move.h \ ${bits_srcdir}/stl_multimap.h \ ${bits_srcdir}/stl_multiset.h \ ${bits_srcdir}/stl_numeric.h \ @@ -139,6 +139,7 @@ ${bits_srcdir}/stl_vector.h \ ${bits_srcdir}/streambuf.tcc \ ${bits_srcdir}/stringfwd.h \ + ${bits_srcdir}/unique_ptr.h \ ${bits_srcdir}/valarray_array.h \ ${bits_srcdir}/valarray_array.tcc \ ${bits_srcdir}/valarray_before.h \ Index: testsuite/util/testsuite_allocator.h =================================================================== --- testsuite/util/testsuite_allocator.h (revision 136999) +++ testsuite/util/testsuite_allocator.h (working copy) @@ -1,7 +1,7 @@ // -*- C++ -*- // Testing allocator for the C++ library testsuite. // -// Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007 +// Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008 // Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free @@ -39,7 +39,7 @@ #include #include #include -#include +#include namespace { Index: testsuite/util/testsuite_iterators.h =================================================================== --- testsuite/util/testsuite_iterators.h (revision 136999) +++ testsuite/util/testsuite_iterators.h (working copy) @@ -1,7 +1,7 @@ // -*- C++ -*- // Iterator Wrappers for the C++ library testsuite. // -// Copyright (C) 2004, 2005, 2006, 2007 Free Software Foundation, Inc. +// Copyright (C) 2004, 2005, 2006, 2007, 2008 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 @@ -38,7 +38,7 @@ #include #include -#include +#include #ifndef _TESTSUITE_ITERATORS #define _TESTSUITE_ITERATORS Index: testsuite/20_util/unique_ptr/requirements/explicit_instantiation/explicit_instantiation.cc =================================================================== --- testsuite/20_util/unique_ptr/requirements/explicit_instantiation/explicit_instantiation.cc (revision 0) +++ testsuite/20_util/unique_ptr/requirements/explicit_instantiation/explicit_instantiation.cc (revision 0) @@ -0,0 +1,25 @@ +// { dg-options "-std=gnu++0x" } +// { dg-do compile } + +// Copyright (C) 2008 Free Software Foundation +// +// 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 of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#include + +template class std::unique_ptr; +template class std::unique_ptr; Index: testsuite/20_util/unique_ptr/assign/assign.cc =================================================================== --- testsuite/20_util/unique_ptr/assign/assign.cc (revision 0) +++ testsuite/20_util/unique_ptr/assign/assign.cc (revision 0) @@ -0,0 +1,52 @@ +// { dg-do compile } +// { dg-options "-std=gnu++0x" } + +// Copyright (C) 2008 Free Software Foundation +// +// 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 of the GNU General Public License as published by the +// Free Software Foundation; either version 2, or (at your option) +// any later version. + +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. + +// You should have received a copy of the GNU General Public License +// along with this library; see the file COPYING. If not, write to +// the Free Software Foundation, 51 Franklin Street, Fifth Floor, +// Boston, MA 02110-1301, USA. + +#include + +struct base { virtual ~base() {} }; +struct derived : base {}; + +void +test01() +{ + std::unique_ptr p1(new derived); + std::unique_ptr p2(new derived); +// p2 = p1; // should not compile + p2 = std::move(p1); + std::unique_ptr p3(new base); +// p3 = p2; // should not compile + p3 = std::move(p2); +} + +void +test02() +{ + std::unique_ptr p1(new int(420)); + std::unique_ptr p2 = p1; // { dg-error "within this context" } +} + +void +test03() +{ + std::unique_ptr p1(new int[3]); + std::unique_ptr p2 = p1; // { dg-error "within this context" } +} +// { dg-excess-errors "is private" }