gcc/libstdc++-v3/include/experimental/memory
2015-05-01 22:26:24 +01:00

258 lines
5.9 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// <experimental/memory> -*- 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
// <http://www.gnu.org/licenses/>.
/** @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 <bits/c++14_warning.h>
#else
#include <memory>
#include <type_traits>
#include <utility>
#include <functional>
namespace std _GLIBCXX_VISIBILITY(default)
{
namespace experimental
{
inline namespace fundamentals_v2
{
_GLIBCXX_BEGIN_NAMESPACE_VERSION
#define __cpp_lib_experimental_observer_ptr 201411
template <typename _Tp>
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 ctor
constexpr observer_ptr() noexcept
: __t()
{ }
// pointer-accepting ctors
constexpr observer_ptr(nullptr_t) noexcept
: __t()
{ }
constexpr explicit observer_ptr(__pointer __p) noexcept
: __t(__p)
{ }
// copying ctors (in addition to compiler-generated copy ctor)
template <typename _Up,
typename = typename enable_if<
is_convertible<typename add_pointer<_Up>::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<typename _Tp>
void
swap(observer_ptr<_Tp>& __p1, observer_ptr<_Tp>& __p2) noexcept
{
__p1.swap(__p2);
}
template<typename _Tp>
observer_ptr<_Tp>
make_observer(_Tp* __p) noexcept
{
return observer_ptr<_Tp>(__p);
}
template<typename _Tp, typename _Up>
bool
operator==(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2)
{
return __p1.get() == __p2.get();
}
template<typename _Tp, typename _Up>
bool
operator!=(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2)
{
return !(__p1 == __p2);
}
template<typename _Tp>
bool
operator==(observer_ptr<_Tp> __p, nullptr_t) noexcept
{
return !__p;
}
template<typename _Tp>
bool
operator==(nullptr_t, observer_ptr<_Tp> __p) noexcept
{
return !__p;
}
template<typename _Tp>
bool
operator!=(observer_ptr<_Tp> __p, nullptr_t) noexcept
{
return bool(__p);
}
template<typename _Tp>
bool
operator!=(nullptr_t, observer_ptr<_Tp> __p) noexcept
{
return bool(__p);
}
template<typename _Tp, typename _Up>
bool
operator<(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2)
{
return std::less<typename common_type<typename add_pointer<_Tp>::type,
typename add_pointer<_Up>::type
>::type
>{}(__p1.get(), __p2.get());
}
template<typename _Tp, typename _Up>
bool
operator>(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2)
{
return __p2 < __p1;
}
template<typename _Tp, typename _Up>
bool
operator<=(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2)
{
return !(__p2 < __p1);
}
template<typename _Tp, typename _Up>
bool
operator>=(observer_ptr<_Tp> __p1, observer_ptr<_Up> __p2)
{
return !(__p1 < __p2);
}
_GLIBCXX_END_NAMESPACE_VERSION
} // namespace fundamentals_v2
} // namespace experimental
template <typename _Tp>
struct hash<experimental::observer_ptr<_Tp>>
{
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<typename add_pointer<_Tp>::type> {}(__t.get())))
{
return hash<typename add_pointer<_Tp>::type> {}(__t.get());
}
};
} // namespace std
#endif // __cplusplus <= 201103L
#endif // _GLIBCXX_EXPERIMENTAL_MEMORY