libstdc++
refwrap.h
00001 // Implementation of std::reference_wrapper -*- C++ -*-
00002 
00003 // Copyright (C) 2004-2017 Free Software Foundation, Inc.
00004 //
00005 // This file is part of the GNU ISO C++ Library.  This library is free
00006 // software; you can redistribute it and/or modify it under the
00007 // terms of the GNU General Public License as published by the
00008 // Free Software Foundation; either version 3, or (at your option)
00009 // any later version.
00010 
00011 // This library is distributed in the hope that it will be useful,
00012 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 // GNU General Public License for more details.
00015 
00016 // Under Section 7 of GPL version 3, you are granted additional
00017 // permissions described in the GCC Runtime Library Exception, version
00018 // 3.1, as published by the Free Software Foundation.
00019 
00020 // You should have received a copy of the GNU General Public License and
00021 // a copy of the GCC Runtime Library Exception along with this program;
00022 // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
00023 // <http://www.gnu.org/licenses/>.
00024 
00025 /** @file include/bits/bind.h
00026  *  This is an internal header file, included by other library headers.
00027  *  Do not attempt to use it directly. @headername{functional}
00028  */
00029 
00030 #ifndef _GLIBCXX_REFWRAP_H
00031 #define _GLIBCXX_REFWRAP_H 1
00032 
00033 #pragma GCC system_header
00034 
00035 #if __cplusplus < 201103L
00036 # include <bits/c++0x_warning.h>
00037 #else
00038 
00039 #include <bits/move.h>
00040 #include <bits/invoke.h>
00041 #include <bits/stl_function.h> // for unary_function and binary_function
00042 
00043 namespace std _GLIBCXX_VISIBILITY(default)
00044 {
00045 _GLIBCXX_BEGIN_NAMESPACE_VERSION
00046 
00047   /// If we have found a result_type, extract it.
00048   template<typename _Functor, typename = __void_t<>>
00049     struct _Maybe_get_result_type
00050     { };
00051 
00052   template<typename _Functor>
00053     struct _Maybe_get_result_type<_Functor,
00054                                   __void_t<typename _Functor::result_type>>
00055     { typedef typename _Functor::result_type result_type; };
00056 
00057   /**
00058    *  Base class for any function object that has a weak result type, as
00059    *  defined in 20.8.2 [func.require] of C++11.
00060   */
00061   template<typename _Functor>
00062     struct _Weak_result_type_impl
00063     : _Maybe_get_result_type<_Functor>
00064     { };
00065 
00066   /// Retrieve the result type for a function type.
00067   template<typename _Res, typename... _ArgTypes>
00068     struct _Weak_result_type_impl<_Res(_ArgTypes...)>
00069     { typedef _Res result_type; };
00070 
00071   template<typename _Res, typename... _ArgTypes>
00072     struct _Weak_result_type_impl<_Res(_ArgTypes......)>
00073     { typedef _Res result_type; };
00074 
00075   template<typename _Res, typename... _ArgTypes>
00076     struct _Weak_result_type_impl<_Res(_ArgTypes...) const>
00077     { typedef _Res result_type; };
00078 
00079   template<typename _Res, typename... _ArgTypes>
00080     struct _Weak_result_type_impl<_Res(_ArgTypes......) const>
00081     { typedef _Res result_type; };
00082 
00083   template<typename _Res, typename... _ArgTypes>
00084     struct _Weak_result_type_impl<_Res(_ArgTypes...) volatile>
00085     { typedef _Res result_type; };
00086 
00087   template<typename _Res, typename... _ArgTypes>
00088     struct _Weak_result_type_impl<_Res(_ArgTypes......) volatile>
00089     { typedef _Res result_type; };
00090 
00091   template<typename _Res, typename... _ArgTypes>
00092     struct _Weak_result_type_impl<_Res(_ArgTypes...) const volatile>
00093     { typedef _Res result_type; };
00094 
00095   template<typename _Res, typename... _ArgTypes>
00096     struct _Weak_result_type_impl<_Res(_ArgTypes......) const volatile>
00097     { typedef _Res result_type; };
00098 
00099   /// Retrieve the result type for a function reference.
00100   template<typename _Res, typename... _ArgTypes>
00101     struct _Weak_result_type_impl<_Res(&)(_ArgTypes...)>
00102     { typedef _Res result_type; };
00103 
00104   template<typename _Res, typename... _ArgTypes>
00105     struct _Weak_result_type_impl<_Res(&)(_ArgTypes......)>
00106     { typedef _Res result_type; };
00107 
00108   /// Retrieve the result type for a function pointer.
00109   template<typename _Res, typename... _ArgTypes>
00110     struct _Weak_result_type_impl<_Res(*)(_ArgTypes...)>
00111     { typedef _Res result_type; };
00112 
00113   template<typename _Res, typename... _ArgTypes>
00114     struct _Weak_result_type_impl<_Res(*)(_ArgTypes......)>
00115     { typedef _Res result_type; };
00116 
00117   /// Retrieve result type for a member function pointer.
00118   template<typename _Res, typename _Class, typename... _ArgTypes>
00119     struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes...)>
00120     { typedef _Res result_type; };
00121 
00122   template<typename _Res, typename _Class, typename... _ArgTypes>
00123     struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes......)>
00124     { typedef _Res result_type; };
00125 
00126   /// Retrieve result type for a const member function pointer.
00127   template<typename _Res, typename _Class, typename... _ArgTypes>
00128     struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes...) const>
00129     { typedef _Res result_type; };
00130 
00131   template<typename _Res, typename _Class, typename... _ArgTypes>
00132     struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes......) const>
00133     { typedef _Res result_type; };
00134 
00135   /// Retrieve result type for a volatile member function pointer.
00136   template<typename _Res, typename _Class, typename... _ArgTypes>
00137     struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes...) volatile>
00138     { typedef _Res result_type; };
00139 
00140   template<typename _Res, typename _Class, typename... _ArgTypes>
00141     struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes......) volatile>
00142     { typedef _Res result_type; };
00143 
00144   /// Retrieve result type for a const volatile member function pointer.
00145   template<typename _Res, typename _Class, typename... _ArgTypes>
00146     struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes...)
00147                                   const volatile>
00148     { typedef _Res result_type; };
00149 
00150   template<typename _Res, typename _Class, typename... _ArgTypes>
00151     struct _Weak_result_type_impl<_Res (_Class::*)(_ArgTypes......)
00152                                   const volatile>
00153     { typedef _Res result_type; };
00154 
00155   /**
00156    *  Strip top-level cv-qualifiers from the function object and let
00157    *  _Weak_result_type_impl perform the real work.
00158   */
00159   template<typename _Functor>
00160     struct _Weak_result_type
00161     : _Weak_result_type_impl<typename remove_cv<_Functor>::type>
00162     { };
00163 
00164   // Detect nested argument_type.
00165   template<typename _Tp, typename = __void_t<>>
00166     struct _Refwrap_base_arg1
00167     { };
00168 
00169   // Nested argument_type.
00170   template<typename _Tp>
00171     struct _Refwrap_base_arg1<_Tp,
00172                               __void_t<typename _Tp::argument_type>>
00173     {
00174       typedef typename _Tp::argument_type argument_type;
00175     };
00176 
00177   // Detect nested first_argument_type and second_argument_type.
00178   template<typename _Tp, typename = __void_t<>>
00179     struct _Refwrap_base_arg2
00180     { };
00181 
00182   // Nested first_argument_type and second_argument_type.
00183   template<typename _Tp>
00184     struct _Refwrap_base_arg2<_Tp,
00185                               __void_t<typename _Tp::first_argument_type,
00186                                        typename _Tp::second_argument_type>>
00187     {
00188       typedef typename _Tp::first_argument_type first_argument_type;
00189       typedef typename _Tp::second_argument_type second_argument_type;
00190     };
00191 
00192   /**
00193    *  Derives from unary_function or binary_function when it
00194    *  can. Specializations handle all of the easy cases. The primary
00195    *  template determines what to do with a class type, which may
00196    *  derive from both unary_function and binary_function.
00197   */
00198   template<typename _Tp>
00199     struct _Reference_wrapper_base
00200     : _Weak_result_type<_Tp>, _Refwrap_base_arg1<_Tp>, _Refwrap_base_arg2<_Tp>
00201     { };
00202 
00203   // - a function type (unary)
00204   template<typename _Res, typename _T1>
00205     struct _Reference_wrapper_base<_Res(_T1)>
00206     : unary_function<_T1, _Res>
00207     { };
00208 
00209   template<typename _Res, typename _T1>
00210     struct _Reference_wrapper_base<_Res(_T1) const>
00211     : unary_function<_T1, _Res>
00212     { };
00213 
00214   template<typename _Res, typename _T1>
00215     struct _Reference_wrapper_base<_Res(_T1) volatile>
00216     : unary_function<_T1, _Res>
00217     { };
00218 
00219   template<typename _Res, typename _T1>
00220     struct _Reference_wrapper_base<_Res(_T1) const volatile>
00221     : unary_function<_T1, _Res>
00222     { };
00223 
00224   // - a function type (binary)
00225   template<typename _Res, typename _T1, typename _T2>
00226     struct _Reference_wrapper_base<_Res(_T1, _T2)>
00227     : binary_function<_T1, _T2, _Res>
00228     { };
00229 
00230   template<typename _Res, typename _T1, typename _T2>
00231     struct _Reference_wrapper_base<_Res(_T1, _T2) const>
00232     : binary_function<_T1, _T2, _Res>
00233     { };
00234 
00235   template<typename _Res, typename _T1, typename _T2>
00236     struct _Reference_wrapper_base<_Res(_T1, _T2) volatile>
00237     : binary_function<_T1, _T2, _Res>
00238     { };
00239 
00240   template<typename _Res, typename _T1, typename _T2>
00241     struct _Reference_wrapper_base<_Res(_T1, _T2) const volatile>
00242     : binary_function<_T1, _T2, _Res>
00243     { };
00244 
00245   // - a function pointer type (unary)
00246   template<typename _Res, typename _T1>
00247     struct _Reference_wrapper_base<_Res(*)(_T1)>
00248     : unary_function<_T1, _Res>
00249     { };
00250 
00251   // - a function pointer type (binary)
00252   template<typename _Res, typename _T1, typename _T2>
00253     struct _Reference_wrapper_base<_Res(*)(_T1, _T2)>
00254     : binary_function<_T1, _T2, _Res>
00255     { };
00256 
00257   // - a pointer to member function type (unary, no qualifiers)
00258   template<typename _Res, typename _T1>
00259     struct _Reference_wrapper_base<_Res (_T1::*)()>
00260     : unary_function<_T1*, _Res>
00261     { };
00262 
00263   // - a pointer to member function type (binary, no qualifiers)
00264   template<typename _Res, typename _T1, typename _T2>
00265     struct _Reference_wrapper_base<_Res (_T1::*)(_T2)>
00266     : binary_function<_T1*, _T2, _Res>
00267     { };
00268 
00269   // - a pointer to member function type (unary, const)
00270   template<typename _Res, typename _T1>
00271     struct _Reference_wrapper_base<_Res (_T1::*)() const>
00272     : unary_function<const _T1*, _Res>
00273     { };
00274 
00275   // - a pointer to member function type (binary, const)
00276   template<typename _Res, typename _T1, typename _T2>
00277     struct _Reference_wrapper_base<_Res (_T1::*)(_T2) const>
00278     : binary_function<const _T1*, _T2, _Res>
00279     { };
00280 
00281   // - a pointer to member function type (unary, volatile)
00282   template<typename _Res, typename _T1>
00283     struct _Reference_wrapper_base<_Res (_T1::*)() volatile>
00284     : unary_function<volatile _T1*, _Res>
00285     { };
00286 
00287   // - a pointer to member function type (binary, volatile)
00288   template<typename _Res, typename _T1, typename _T2>
00289     struct _Reference_wrapper_base<_Res (_T1::*)(_T2) volatile>
00290     : binary_function<volatile _T1*, _T2, _Res>
00291     { };
00292 
00293   // - a pointer to member function type (unary, const volatile)
00294   template<typename _Res, typename _T1>
00295     struct _Reference_wrapper_base<_Res (_T1::*)() const volatile>
00296     : unary_function<const volatile _T1*, _Res>
00297     { };
00298 
00299   // - a pointer to member function type (binary, const volatile)
00300   template<typename _Res, typename _T1, typename _T2>
00301     struct _Reference_wrapper_base<_Res (_T1::*)(_T2) const volatile>
00302     : binary_function<const volatile _T1*, _T2, _Res>
00303     { };
00304 
00305   /**
00306    *  @brief Primary class template for reference_wrapper.
00307    *  @ingroup functors
00308    *  @{
00309    */
00310   template<typename _Tp>
00311     class reference_wrapper
00312     : public _Reference_wrapper_base<typename remove_cv<_Tp>::type>
00313     {
00314       _Tp* _M_data;
00315 
00316     public:
00317       typedef _Tp type;
00318 
00319       reference_wrapper(_Tp& __indata) noexcept
00320       : _M_data(std::__addressof(__indata))
00321       { }
00322 
00323       reference_wrapper(_Tp&&) = delete;
00324 
00325       reference_wrapper(const reference_wrapper&) = default;
00326 
00327       reference_wrapper&
00328       operator=(const reference_wrapper&) = default;
00329 
00330       operator _Tp&() const noexcept
00331       { return this->get(); }
00332 
00333       _Tp&
00334       get() const noexcept
00335       { return *_M_data; }
00336 
00337       template<typename... _Args>
00338         typename result_of<_Tp&(_Args&&...)>::type
00339         operator()(_Args&&... __args) const
00340         {
00341           return std::__invoke(get(), std::forward<_Args>(__args)...);
00342         }
00343     };
00344 
00345 
00346   /// Denotes a reference should be taken to a variable.
00347   template<typename _Tp>
00348     inline reference_wrapper<_Tp>
00349     ref(_Tp& __t) noexcept
00350     { return reference_wrapper<_Tp>(__t); }
00351 
00352   /// Denotes a const reference should be taken to a variable.
00353   template<typename _Tp>
00354     inline reference_wrapper<const _Tp>
00355     cref(const _Tp& __t) noexcept
00356     { return reference_wrapper<const _Tp>(__t); }
00357 
00358   template<typename _Tp>
00359     void ref(const _Tp&&) = delete;
00360 
00361   template<typename _Tp>
00362     void cref(const _Tp&&) = delete;
00363 
00364   /// Partial specialization.
00365   template<typename _Tp>
00366     inline reference_wrapper<_Tp>
00367     ref(reference_wrapper<_Tp> __t) noexcept
00368     { return ref(__t.get()); }
00369 
00370   /// Partial specialization.
00371   template<typename _Tp>
00372     inline reference_wrapper<const _Tp>
00373     cref(reference_wrapper<_Tp> __t) noexcept
00374     { return cref(__t.get()); }
00375 
00376   // @} group functors
00377 
00378 _GLIBCXX_END_NAMESPACE_VERSION
00379 } // namespace std
00380 
00381 #endif // C++11
00382 
00383 #endif // _GLIBCXX_REFWRAP_H