type_traits/is_constructible.hh

00001 // This file is a part of Catsfoot.
00002 // Copyright (C) 2011  Uni Research
00003 //
00004 // This program is free software: you can redistribute it and/or modify
00005 // it under the terms of the GNU Lesser Public License as published by
00006 // the Free Software Foundation, either version 3 of the License, or
00007 // (at your option) any later version.
00008 //
00009 // This program is distributed in the hope that it will be useful,
00010 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 // GNU Lesser Public License for more details.
00013 //
00014 // You should have received a copy of the GNU Lesser Public License
00015 // along with this program.  If not, see <http://www.gnu.org/licenses/>.
00016 
00017 #ifndef IS_CONSTRUCTIBLE_HH
00018 # define IS_CONSTRUCTIBLE_HH
00019 
00020 # include "always_false.hh"
00021 # include <type_traits>
00022 
00023 namespace catsfoot {
00024 
00026   template <typename T>
00027   struct is_constructible: public std::false_type {
00028     static_assert(details::always_false<T>::value,
00029                   "Bad format of parameter");
00030   };
00031 
00032   namespace details {
00034     template <bool B, typename T>
00035     struct is_constructible_work_around;
00036 
00038     template <typename T, typename... U>
00039     struct is_constructible_work_around<false, T(U...)>:
00040       public std::false_type {
00041     };
00042 
00044     template <typename T>
00045     struct is_constructible_work_around<false, T()>:
00046       public std::true_type {
00047     };
00048 
00051     template <typename T, typename U>
00052     struct is_constructible_work_around<false, T(U)>:
00053       public std::is_explicitly_convertible<U, T> {
00054     };
00055 
00057     template <typename T, typename... U>
00058     struct is_constructible_work_around<true, T(U...)>
00059       : public std::is_constructible<T, U...> {
00060     };
00061   }
00062 
00063 #ifndef SHOULDBE
00064   template <typename T, typename... U>
00065   struct is_constructible<T(U...)>:
00066     public details::
00067     is_constructible_work_around<std::is_class<T>::value, T(U...)> {
00068     };
00069 #else
00070 
00071 
00072   template <typename T, typename... U>
00073   struct is_constructible<T(U...)>:
00074     public std::is_constructible<T, U...> {
00075   };
00076 
00078   template <typename... U>
00079   struct is_constructible<void(U...)>:
00080     public std::false_type {};
00081 #endif
00082 
00083 }
00084 
00085 #endif