diff --git a/libstdc++-v3/ChangeLog b/libstdc++-v3/ChangeLog index a955a0f506d..a899842223c 100644 --- a/libstdc++-v3/ChangeLog +++ b/libstdc++-v3/ChangeLog @@ -1,3 +1,18 @@ +2015-05-01 Ville Voutilainen + + Implement observer_ptr. + * include/Makefile.am: Add new header. + * include/Makefile.in: Regenerate. + * include/experimental/memory: New. + * testsuite/experimental/memory/observer_ptr/assignment/assign.cc: New. + * testsuite/experimental/memory/observer_ptr/cons/cons.cc: New. + * testsuite/experimental/memory/observer_ptr/hash/hash.cc: New. + * testsuite/experimental/memory/observer_ptr/make_observer.cc: New. + * testsuite/experimental/memory/observer_ptr/relops/relops.cc: New. + * testsuite/experimental/memory/observer_ptr/requirements.cc: New. + * testsuite/experimental/memory/observer_ptr/swap/swap.cc: New. + * testsuite/experimental/memory/observer_ptr/typedefs.cc: New. + 2015-05-01 Jonathan Wakely * src/filesystem/path.cc (path::compare): Do not copy strings. diff --git a/libstdc++-v3/include/Makefile.am b/libstdc++-v3/include/Makefile.am index 32be43e7e04..6ba702c4e10 100644 --- a/libstdc++-v3/include/Makefile.am +++ b/libstdc++-v3/include/Makefile.am @@ -653,6 +653,7 @@ experimental_headers = \ ${experimental_srcdir}/functional \ ${experimental_srcdir}/list \ ${experimental_srcdir}/map \ + ${experimental_srcdir}/memory \ ${experimental_srcdir}/optional \ ${experimental_srcdir}/ratio \ ${experimental_srcdir}/set \ diff --git a/libstdc++-v3/include/Makefile.in b/libstdc++-v3/include/Makefile.in index e59ee689a26..f23ff63d540 100644 --- a/libstdc++-v3/include/Makefile.in +++ b/libstdc++-v3/include/Makefile.in @@ -920,6 +920,7 @@ experimental_headers = \ ${experimental_srcdir}/functional \ ${experimental_srcdir}/list \ ${experimental_srcdir}/map \ + ${experimental_srcdir}/memory \ ${experimental_srcdir}/optional \ ${experimental_srcdir}/ratio \ ${experimental_srcdir}/set \ diff --git a/libstdc++-v3/include/experimental/memory b/libstdc++-v3/include/experimental/memory new file mode 100644 index 00000000000..d3c95094ea9 --- /dev/null +++ b/libstdc++-v3/include/experimental/memory @@ -0,0 +1,255 @@ +// -*- C++ -*- + +// Copyright (C) 2015 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 3, 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. + +// Under Section 7 of GPL version 3, you are granted additional +// permissions described in the GCC Runtime Library Exception, version +// 3.1, as published by the Free Software Foundation. + +// You should have received a copy of the GNU General Public License and +// a copy of the GCC Runtime Library Exception along with this program; +// see the files COPYING3 and COPYING.RUNTIME respectively. If not, see +// . + +/** @file experimental/memory + * This is a TS C++ Library header. + */ + +// +// N4336 Working Draft, C++ Extensions for Library Fundamentals, Version 2 +// + +#ifndef _GLIBCXX_EXPERIMENTAL_MEMORY +#define _GLIBCXX_EXPERIMENTAL_MEMORY 1 + +#pragma GCC system_header + +#if __cplusplus <= 201103L +# include +#else + +#include +#include +#include +#include + +namespace std _GLIBCXX_VISIBILITY(default) +{ +namespace experimental +{ +inline namespace fundamentals_v2 +{ +_GLIBCXX_BEGIN_NAMESPACE_VERSION + + template + class observer_ptr + { + public: + // publish our template parameter and variations thereof + using element_type = _Tp; + using __pointer = add_pointer_t<_Tp>; // exposition-only + using __reference = add_lvalue_reference_t<_Tp>; // exposition-only + + // 3.2.2, observer_ptr constructors + // default c’tor + constexpr observer_ptr() noexcept + : __t() + { } + + // pointer-accepting c’tors + constexpr observer_ptr(nullptr_t) noexcept + : __t() + { } + + constexpr explicit observer_ptr(__pointer __p) noexcept + : __t(__p) + { } + + // copying c’tors (in addition to compiler-generated copy c’tor) + template ::type, __pointer + >::value + >::type> + constexpr observer_ptr(observer_ptr<_Up> __p) noexcept + : __t(__p.get()) + { + } + + // 3.2.3, observer_ptr observers + constexpr __pointer + get() const noexcept + { + return __t; + } + + constexpr __reference + operator*() const + { + return *get(); + } + + constexpr __pointer + operator->() const noexcept + { + return get(); + } + + constexpr explicit operator bool() const noexcept + { + return get() != nullptr; + } + + // 3.2.4, observer_ptr conversions + constexpr explicit operator __pointer() const noexcept + { + return get(); + } + + // 3.2.5, observer_ptr modifiers + constexpr __pointer + release() noexcept + { + __pointer tmp = get(); + reset(); + return tmp; + } + + constexpr void + reset(__pointer __p = nullptr) noexcept + { + __t = __p; + } + + constexpr void + swap(observer_ptr& __p) noexcept + { + std::swap(__t, __p.__t); + } + + private: + __pointer __t; + }; // observer_ptr<> + + template + void + swap(observer_ptr<_Tp>& __p1, observer_ptr<_Tp>& __p2) noexcept + { + __p1.swap(__p2); + } + + template + observer_ptr<_Tp> + make_observer(_Tp* __p) noexcept + { + return observer_ptr<_Tp>(__p); + } + + template + bool + operator==(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2) + { + return __p1.get() == __p2.get(); + } + + template + bool + operator!=(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2) + { + return !(__p1 == __p2); + } + + template + bool + operator==(observer_ptr<_Tp> __p, nullptr_t) noexcept + { + return !__p; + } + + template + bool + operator==(nullptr_t, observer_ptr<_Tp> __p) noexcept + { + return !__p; + } + + template + bool + operator!=(observer_ptr<_Tp> __p, nullptr_t) noexcept + { + return bool(__p); + } + + template + bool + operator!=(nullptr_t, observer_ptr<_Tp> __p) noexcept + { + return bool(__p); + } + + template + bool + operator<(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2) + { + return std::less::type, + typename add_pointer<_Up>::type + >::type + >{}(__p1.get(), __p2.get()); + } + + template + bool + operator>(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2) + { + return __p2 < __p1; + } + + template + bool + operator<=(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2) + { + return !(__p2 < __p1); + } + + template + bool + operator>=(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2) + { + return !(__p1 < __p2); + } + +_GLIBCXX_END_NAMESPACE_VERSION +} // namespace fundamentals_v2 +} // namespace experimental + +template + struct hash> + { + using result_type = size_t; + using argument_type = experimental::observer_ptr<_Tp>; + + size_t + operator()(const experimental::observer_ptr<_Tp>& __t) const + noexcept(noexcept(hash::type> {}(__t.get()))) + { + return hash::type> {}(__t.get()); + } + + }; + +} // namespace std + +#endif // __cplusplus <= 201103L + +#endif // _GLIBCXX_EXPERIMENTAL_MEMORY diff --git a/libstdc++-v3/testsuite/experimental/memory/observer_ptr/assignment/assign.cc b/libstdc++-v3/testsuite/experimental/memory/observer_ptr/assignment/assign.cc new file mode 100644 index 00000000000..6ccf4074c35 --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/memory/observer_ptr/assignment/assign.cc @@ -0,0 +1,89 @@ +// { dg-options "-std=gnu++14" } +// { dg-do run } + +// Copyright (C) 2015 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 3, 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 moved_to of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +#include +#include + +using std::experimental::observer_ptr; + +struct B {}; +struct D : B {}; + +void test01() +{ + observer_ptr a, b; + a = b; + VERIFY(a == b); +} + +void test02() +{ + int x{}; + observer_ptr a; + observer_ptr b{&x}; + VERIFY(a != b); + a = b; + VERIFY(a == b); +} + +void test03() +{ + int x{}; + observer_ptr a; + observer_ptr b{&x}; + VERIFY(a != b); + a = b; + VERIFY(a == b); +} + +void test04() +{ + D x{}; + observer_ptr a; + observer_ptr b{&x}; + VERIFY(a != b); + a = b; + VERIFY(a == b); +} + +constexpr bool test05_helper(observer_ptr a, + observer_ptr b) +{ + a = b; + return (a.get() == b.get()); +} + +void test05() +{ + static constexpr int x{}; + constexpr observer_ptr a; + constexpr observer_ptr b{&x}; + constexpr bool assigned = test05_helper(a, b); + VERIFY(assigned); +} + +int main() +{ + test01(); + test02(); + test03(); + test04(); + test05(); +} diff --git a/libstdc++-v3/testsuite/experimental/memory/observer_ptr/cons/cons.cc b/libstdc++-v3/testsuite/experimental/memory/observer_ptr/cons/cons.cc new file mode 100644 index 00000000000..c6c435bdd04 --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/memory/observer_ptr/cons/cons.cc @@ -0,0 +1,92 @@ +// { dg-options "-std=gnu++14" } +// { dg-do run } + +// Copyright (C) 2015 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 3, 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 moved_to of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +#include +#include +#include + +using std::experimental::observer_ptr; + +struct B {}; +struct D : B {}; + +void test01() +{ + observer_ptr a; + VERIFY(!a); + observer_ptr b{nullptr}; + VERIFY(!b); +} + +void test02() +{ + int x{}; + observer_ptr a{&x}; + observer_ptr b{a}; + VERIFY(a == b); +} + +void test03() +{ + int x{}; + observer_ptr a; + observer_ptr b{a}; + VERIFY(a == b); +} + +void test04() +{ + D x{}; + observer_ptr a{&x}; + observer_ptr b{a}; + VERIFY(a == b); +} + +void test05() +{ + D x{}; + observer_ptr a{&x}; + observer_ptr b{std::move(a)}; + VERIFY(a == b); +} + +void test06() +{ + static constexpr D x{}; + constexpr observer_ptr a{&x}; + constexpr observer_ptr b{std::move(a)}; + VERIFY(a == b); + constexpr observer_ptr c{a}; + VERIFY(a == b && a == c && b == c); + constexpr observer_ptr d; + constexpr observer_ptr e{nullptr}; + VERIFY(!d); + VERIFY(!e); +} + +int main() +{ + test01(); + test02(); + test03(); + test04(); + test05(); + test06(); +} diff --git a/libstdc++-v3/testsuite/experimental/memory/observer_ptr/hash/hash.cc b/libstdc++-v3/testsuite/experimental/memory/observer_ptr/hash/hash.cc new file mode 100644 index 00000000000..eb318fcf9fa --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/memory/observer_ptr/hash/hash.cc @@ -0,0 +1,46 @@ +// { dg-options "-std=gnu++14" } +// { dg-do run } + +// Copyright (C) 2015 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 3, 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 moved_to of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +#include +#include + +using std::experimental::observer_ptr; + +struct B {}; +struct D : B {}; + +void test01() +{ + observer_ptr a; + VERIFY(std::hash>{}(a) == std::hash{}(nullptr)); +} + +void test02() +{ + int x{}; + observer_ptr a{&x}; + VERIFY(std::hash>{}(a) == std::hash{}(&x)); +} + +int main() +{ + test01(); + test02(); +} diff --git a/libstdc++-v3/testsuite/experimental/memory/observer_ptr/make_observer.cc b/libstdc++-v3/testsuite/experimental/memory/observer_ptr/make_observer.cc new file mode 100644 index 00000000000..b6075fab9c3 --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/memory/observer_ptr/make_observer.cc @@ -0,0 +1,32 @@ +// { dg-options "-std=gnu++14" } +// { dg-do run } + +// Copyright (C) 2015 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 3, 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 moved_to of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +#include +#include + +int main() +{ + const int i = 42; + auto o = std::experimental::make_observer(&i); + static_assert( std::is_same>(), "" ); + VERIFY( o && *o == 42 ); + VERIFY( o.get() == &i ); +} diff --git a/libstdc++-v3/testsuite/experimental/memory/observer_ptr/relops/relops.cc b/libstdc++-v3/testsuite/experimental/memory/observer_ptr/relops/relops.cc new file mode 100644 index 00000000000..9cf39de7779 --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/memory/observer_ptr/relops/relops.cc @@ -0,0 +1,80 @@ +// { dg-options "-std=gnu++14" } +// { dg-do run } + +// Copyright (C) 2015 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 3, 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 moved_to of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +#include +#include + +using std::experimental::observer_ptr; + +void test01() +{ + observer_ptr a, b; + VERIFY(a == b); +} + +void test02() +{ + int x[2]{}; + observer_ptr a{&x[0]}; + observer_ptr b{&x[1]}; + VERIFY(a != b); + VERIFY(a < b); + VERIFY(a <= b); + VERIFY(b >= a); + VERIFY(b > a); +} + +void test03() +{ + int x{}; + observer_ptr a{&x}; + observer_ptr b{&x}; + VERIFY(a == b); +} + +void test04() +{ + static constexpr int x[2]{}; + constexpr observer_ptr a{&x[0]}; + constexpr observer_ptr b{&x[1]}; + VERIFY(a != b); + VERIFY(a < b); + VERIFY(a <= b); + VERIFY(b >= a); + VERIFY(b > a); +} + +void test05() +{ + static constexpr int x{}; + constexpr observer_ptr a{&x}; + constexpr observer_ptr b{&x}; + VERIFY(a == b); +} + + +int main() +{ + test01(); + test02(); + test03(); + test04(); + test05(); +} diff --git a/libstdc++-v3/testsuite/experimental/memory/observer_ptr/requirements.cc b/libstdc++-v3/testsuite/experimental/memory/observer_ptr/requirements.cc new file mode 100644 index 00000000000..36ffcab92f8 --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/memory/observer_ptr/requirements.cc @@ -0,0 +1,65 @@ +// { dg-options "-std=gnu++14" } +// { dg-do compile } + +// Copyright (C) 2015 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 3, 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 moved_to of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +#include + +using std::experimental::observer_ptr; + +struct nontrivial {nontrivial() {}}; +struct other {}; +struct base {}; +struct derived : base {}; + +static_assert(!std::is_trivially_constructible< + observer_ptr>::value, ""); +static_assert(std::is_trivially_copyable< + observer_ptr>::value, ""); +static_assert(std::is_trivially_destructible< + observer_ptr>::value, ""); + +static_assert(std::is_constructible< + observer_ptr, nontrivial*>::value, + ""); +static_assert(std::is_constructible, base*>::value, ""); +static_assert(std::is_constructible, derived*>::value, ""); +static_assert(!std::is_constructible, other*>::value, ""); +static_assert(std::is_constructible< + observer_ptr, observer_ptr>::value, ""); +static_assert(std::is_constructible< + observer_ptr, observer_ptr>::value, ""); +static_assert(!std::is_constructible< + observer_ptr, observer_ptr>::value, ""); + +static_assert(!std::is_assignable< + observer_ptr, nontrivial*>::value, + ""); +static_assert(std::is_assignable< + observer_ptr, observer_ptr>::value, + ""); +static_assert(std::is_assignable, + observer_ptr>::value, ""); +static_assert(std::is_assignable, + observer_ptr>::value, ""); +static_assert(!std::is_assignable< + observer_ptr, observer_ptr>::value, ""); +static_assert(std::is_assignable, + observer_ptr>::value, ""); +static_assert(!std::is_assignable, + observer_ptr>::value, ""); diff --git a/libstdc++-v3/testsuite/experimental/memory/observer_ptr/swap/swap.cc b/libstdc++-v3/testsuite/experimental/memory/observer_ptr/swap/swap.cc new file mode 100644 index 00000000000..f7bfc2d9778 --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/memory/observer_ptr/swap/swap.cc @@ -0,0 +1,67 @@ +// { dg-options "-std=gnu++14" } +// { dg-do run } + +// Copyright (C) 2015 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 3, 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 moved_to of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +#include +#include + +using std::experimental::observer_ptr; + +struct B {}; +struct D : B {}; + +void test01() +{ + observer_ptr a, b; + VERIFY(a == b); + swap(a, b); + VERIFY(a == b); +} + +void test02() +{ + int x{}; + observer_ptr a; + observer_ptr b{&x}; + VERIFY(!a); + VERIFY(b); + swap(a, b); + VERIFY(a); + VERIFY(!b); +} + +void test03() +{ + int x[2]{1,2}; + observer_ptr a{&x[0]}; + observer_ptr b{&x[1]}; + VERIFY(*a == 1); + VERIFY(*b == 2); + swap(a, b); + VERIFY(*a == 2); + VERIFY(*b == 1); +} + + +int main() +{ + test01(); + test02(); + test03(); +} diff --git a/libstdc++-v3/testsuite/experimental/memory/observer_ptr/typedefs.cc b/libstdc++-v3/testsuite/experimental/memory/observer_ptr/typedefs.cc new file mode 100644 index 00000000000..b738232297b --- /dev/null +++ b/libstdc++-v3/testsuite/experimental/memory/observer_ptr/typedefs.cc @@ -0,0 +1,32 @@ +// { dg-options "-std=gnu++14" } +// { dg-do compile } + +// Copyright (C) 2015 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 3, 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 moved_to of the GNU General Public License along +// with this library; see the file COPYING3. If not see +// . + +#include +#include + +static_assert(std::is_same< + std::experimental::observer_ptr::element_type, + int>::value, ""); +static_assert(std::is_same< + std::experimental::observer_ptr::element_type, + const int>::value, ""); +static_assert(std::is_same< + std::experimental::observer_ptr::element_type, + volatile int>::value, "");