1  // <bits/enable_special_members.h> -*- C++ -*-
       2  
       3  // Copyright (C) 2013-2023 Free Software Foundation, Inc.
       4  //
       5  // This file is part of the GNU ISO C++ Library.  This library is free
       6  // software; you can redistribute it and/or modify it under the
       7  // terms of the GNU General Public License as published by the
       8  // Free Software Foundation; either version 3, or (at your option)
       9  // any later version.
      10  
      11  // This library is distributed in the hope that it will be useful,
      12  // but WITHOUT ANY WARRANTY; without even the implied warranty of
      13  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      14  // GNU General Public License for more details.
      15  
      16  // Under Section 7 of GPL version 3, you are granted additional
      17  // permissions described in the GCC Runtime Library Exception, version
      18  // 3.1, as published by the Free Software Foundation.
      19  
      20  // You should have received a copy of the GNU General Public License and
      21  // a copy of the GCC Runtime Library Exception along with this program;
      22  // see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
      23  // <http://www.gnu.org/licenses/>.
      24  
      25  /** @file bits/enable_special_members.h
      26   *  This is an internal header file, included by other library headers.
      27   *  Do not attempt to use it directly.
      28   */
      29  
      30  #ifndef _ENABLE_SPECIAL_MEMBERS_H
      31  #define _ENABLE_SPECIAL_MEMBERS_H 1
      32  
      33  #pragma GCC system_header
      34  
      35  #include <bits/c++config.h>
      36  
      37  namespace std _GLIBCXX_VISIBILITY(default)
      38  {
      39  _GLIBCXX_BEGIN_NAMESPACE_VERSION
      40  /// @cond undocumented
      41  
      42    struct _Enable_default_constructor_tag
      43    {
      44      explicit constexpr _Enable_default_constructor_tag() = default;
      45    };
      46  
      47  /**
      48    * @brief A mixin helper to conditionally enable or disable the default
      49    * constructor.
      50    * @sa _Enable_special_members
      51    */
      52  template<bool _Switch, typename _Tag = void>
      53    struct _Enable_default_constructor
      54    {
      55      constexpr _Enable_default_constructor() noexcept = default;
      56      constexpr _Enable_default_constructor(_Enable_default_constructor const&)
      57        noexcept  = default;
      58      constexpr _Enable_default_constructor(_Enable_default_constructor&&)
      59        noexcept = default;
      60      _Enable_default_constructor&
      61      operator=(_Enable_default_constructor const&) noexcept = default;
      62      _Enable_default_constructor&
      63      operator=(_Enable_default_constructor&&) noexcept = default;
      64  
      65      // Can be used in other ctors.
      66      constexpr explicit
      67      _Enable_default_constructor(_Enable_default_constructor_tag) { }
      68    };
      69  
      70  
      71  /**
      72    * @brief A mixin helper to conditionally enable or disable the default
      73    * destructor.
      74    * @sa _Enable_special_members
      75    */
      76  template<bool _Switch, typename _Tag = void>
      77    struct _Enable_destructor { };
      78  
      79  /**
      80    * @brief A mixin helper to conditionally enable or disable the copy/move
      81    * special members.
      82    * @sa _Enable_special_members
      83    */
      84  template<bool _Copy, bool _CopyAssignment,
      85           bool _Move, bool _MoveAssignment,
      86           typename _Tag = void>
      87    struct _Enable_copy_move { };
      88  
      89  /**
      90    * @brief A mixin helper to conditionally enable or disable the special
      91    * members.
      92    *
      93    * The @c _Tag type parameter is to make mixin bases unique and thus avoid
      94    * ambiguities.
      95    */
      96  template<bool _Default, bool _Destructor,
      97           bool _Copy, bool _CopyAssignment,
      98           bool _Move, bool _MoveAssignment,
      99           typename _Tag = void>
     100    struct _Enable_special_members
     101    : private _Enable_default_constructor<_Default, _Tag>,
     102      private _Enable_destructor<_Destructor, _Tag>,
     103      private _Enable_copy_move<_Copy, _CopyAssignment,
     104                                _Move, _MoveAssignment,
     105                                _Tag>
     106    { };
     107  
     108  // Boilerplate follows.
     109  
     110  template<typename _Tag>
     111    struct _Enable_default_constructor<false, _Tag>
     112    {
     113      constexpr _Enable_default_constructor() noexcept = delete;
     114      constexpr _Enable_default_constructor(_Enable_default_constructor const&)
     115        noexcept  = default;
     116      constexpr _Enable_default_constructor(_Enable_default_constructor&&)
     117        noexcept = default;
     118      _Enable_default_constructor&
     119      operator=(_Enable_default_constructor const&) noexcept = default;
     120      _Enable_default_constructor&
     121      operator=(_Enable_default_constructor&&) noexcept = default;
     122  
     123      // Can be used in other ctors.
     124      constexpr explicit
     125      _Enable_default_constructor(_Enable_default_constructor_tag) { }
     126    };
     127  
     128  template<typename _Tag>
     129    struct _Enable_destructor<false, _Tag>
     130    { ~_Enable_destructor() noexcept = delete; };
     131  
     132  template<typename _Tag>
     133    struct _Enable_copy_move<false, true, true, true, _Tag>
     134    {
     135      constexpr _Enable_copy_move() noexcept                          = default;
     136      constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept  = delete;
     137      constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept       = default;
     138      _Enable_copy_move&
     139      operator=(_Enable_copy_move const&) noexcept                    = default;
     140      _Enable_copy_move&
     141      operator=(_Enable_copy_move&&) noexcept                         = default;
     142    };
     143  
     144  template<typename _Tag>
     145    struct _Enable_copy_move<true, false, true, true, _Tag>
     146    {
     147      constexpr _Enable_copy_move() noexcept                          = default;
     148      constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept  = default;
     149      constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept       = default;
     150      _Enable_copy_move&
     151      operator=(_Enable_copy_move const&) noexcept                    = delete;
     152      _Enable_copy_move&
     153      operator=(_Enable_copy_move&&) noexcept                         = default;
     154    };
     155  
     156  template<typename _Tag>
     157    struct _Enable_copy_move<false, false, true, true, _Tag>
     158    {
     159      constexpr _Enable_copy_move() noexcept                          = default;
     160      constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept  = delete;
     161      constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept       = default;
     162      _Enable_copy_move&
     163      operator=(_Enable_copy_move const&) noexcept                    = delete;
     164      _Enable_copy_move&
     165      operator=(_Enable_copy_move&&) noexcept                         = default;
     166    };
     167  
     168  template<typename _Tag>
     169    struct _Enable_copy_move<true, true, false, true, _Tag>
     170    {
     171      constexpr _Enable_copy_move() noexcept                          = default;
     172      constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept  = default;
     173      constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept       = delete;
     174      _Enable_copy_move&
     175      operator=(_Enable_copy_move const&) noexcept                    = default;
     176      _Enable_copy_move&
     177      operator=(_Enable_copy_move&&) noexcept                         = default;
     178    };
     179  
     180  template<typename _Tag>
     181    struct _Enable_copy_move<false, true, false, true, _Tag>
     182    {
     183      constexpr _Enable_copy_move() noexcept                          = default;
     184      constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept  = delete;
     185      constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept       = delete;
     186      _Enable_copy_move&
     187      operator=(_Enable_copy_move const&) noexcept                    = default;
     188      _Enable_copy_move&
     189      operator=(_Enable_copy_move&&) noexcept                         = default;
     190    };
     191  
     192  template<typename _Tag>
     193    struct _Enable_copy_move<true, false, false, true, _Tag>
     194    {
     195      constexpr _Enable_copy_move() noexcept                          = default;
     196      constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept  = default;
     197      constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept       = delete;
     198      _Enable_copy_move&
     199      operator=(_Enable_copy_move const&) noexcept                    = delete;
     200      _Enable_copy_move&
     201      operator=(_Enable_copy_move&&) noexcept                         = default;
     202    };
     203  
     204  template<typename _Tag>
     205    struct _Enable_copy_move<false, false, false, true, _Tag>
     206    {
     207      constexpr _Enable_copy_move() noexcept                          = default;
     208      constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept  = delete;
     209      constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept       = delete;
     210      _Enable_copy_move&
     211      operator=(_Enable_copy_move const&) noexcept                    = delete;
     212      _Enable_copy_move&
     213      operator=(_Enable_copy_move&&) noexcept                         = default;
     214    };
     215  
     216  template<typename _Tag>
     217    struct _Enable_copy_move<true, true, true, false, _Tag>
     218    {
     219      constexpr _Enable_copy_move() noexcept                          = default;
     220      constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept  = default;
     221      constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept       = default;
     222      _Enable_copy_move&
     223      operator=(_Enable_copy_move const&) noexcept                    = default;
     224      _Enable_copy_move&
     225      operator=(_Enable_copy_move&&) noexcept                         = delete;
     226    };
     227  
     228  template<typename _Tag>
     229    struct _Enable_copy_move<false, true, true, false, _Tag>
     230    {
     231      constexpr _Enable_copy_move() noexcept                          = default;
     232      constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept  = delete;
     233      constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept       = default;
     234      _Enable_copy_move&
     235      operator=(_Enable_copy_move const&) noexcept                    = default;
     236      _Enable_copy_move&
     237      operator=(_Enable_copy_move&&) noexcept                         = delete;
     238    };
     239  
     240  template<typename _Tag>
     241    struct _Enable_copy_move<true, false, true, false, _Tag>
     242    {
     243      constexpr _Enable_copy_move() noexcept                          = default;
     244      constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept  = default;
     245      constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept       = default;
     246      _Enable_copy_move&
     247      operator=(_Enable_copy_move const&) noexcept                    = delete;
     248      _Enable_copy_move&
     249      operator=(_Enable_copy_move&&) noexcept                         = delete;
     250    };
     251  
     252  template<typename _Tag>
     253    struct _Enable_copy_move<false, false, true, false, _Tag>
     254    {
     255      constexpr _Enable_copy_move() noexcept                          = default;
     256      constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept  = delete;
     257      constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept       = default;
     258      _Enable_copy_move&
     259      operator=(_Enable_copy_move const&) noexcept                    = delete;
     260      _Enable_copy_move&
     261      operator=(_Enable_copy_move&&) noexcept                         = delete;
     262    };
     263  
     264  template<typename _Tag>
     265    struct _Enable_copy_move<true, true, false, false, _Tag>
     266    {
     267      constexpr _Enable_copy_move() noexcept                          = default;
     268      constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept  = default;
     269      constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept       = delete;
     270      _Enable_copy_move&
     271      operator=(_Enable_copy_move const&) noexcept                    = default;
     272      _Enable_copy_move&
     273      operator=(_Enable_copy_move&&) noexcept                         = delete;
     274    };
     275  
     276  template<typename _Tag>
     277    struct _Enable_copy_move<false, true, false, false, _Tag>
     278    {
     279      constexpr _Enable_copy_move() noexcept                          = default;
     280      constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept  = delete;
     281      constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept       = delete;
     282      _Enable_copy_move&
     283      operator=(_Enable_copy_move const&) noexcept                    = default;
     284      _Enable_copy_move&
     285      operator=(_Enable_copy_move&&) noexcept                         = delete;
     286    };
     287  
     288  template<typename _Tag>
     289    struct _Enable_copy_move<true, false, false, false, _Tag>
     290    {
     291      constexpr _Enable_copy_move() noexcept                          = default;
     292      constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept  = default;
     293      constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept       = delete;
     294      _Enable_copy_move&
     295      operator=(_Enable_copy_move const&) noexcept                    = delete;
     296      _Enable_copy_move&
     297      operator=(_Enable_copy_move&&) noexcept                         = delete;
     298    };
     299  
     300  template<typename _Tag>
     301    struct _Enable_copy_move<false, false, false, false, _Tag>
     302    {
     303      constexpr _Enable_copy_move() noexcept                          = default;
     304      constexpr _Enable_copy_move(_Enable_copy_move const&) noexcept  = delete;
     305      constexpr _Enable_copy_move(_Enable_copy_move&&) noexcept       = delete;
     306      _Enable_copy_move&
     307      operator=(_Enable_copy_move const&) noexcept                    = delete;
     308      _Enable_copy_move&
     309      operator=(_Enable_copy_move&&) noexcept                         = delete;
     310    };
     311  
     312  /// @endcond
     313  _GLIBCXX_END_NAMESPACE_VERSION
     314  } // namespace std
     315  
     316  #endif // _ENABLE_SPECIAL_MEMBERS_H