1 /*!
2  * \file   include/TFEL/Metaprogramming/HasConstIterator.hxx
3  * \brief
4  *
5  * \author Thomas Helfer
6  * \date   19 oct 2006
7  * \copyright Copyright (C) 2006-2018 CEA/DEN, EDF R&D. All rights
8  * reserved.
9  * This project is publicly released under either the GNU GPL Licence
10  * or the CECILL-A licence. A copy of thoses licences are delivered
11  * with the sources of TFEL. CEA or EDF may also distribute this
12  * project under specific licensing conditions.
13  */
14 
15 #ifndef LIB_TFEL_HASCONSTITERATOR_HXX
16 #define LIB_TFEL_HASCONSTITERATOR_HXX
17 
18 #include"TFEL/Config/TFELConfig.hxx"
19 #include<type_traits>
20 
21 namespace tfel{
22 
23   namespace meta{
24 
25     /*!
26      * \class HasConstIterator
27      * \param typename A, type tested.
28      * \return bool cond, true if the type defines the iterator.
29      */
30     template<typename A>
31     class TFEL_VISIBILITY_LOCAL HasConstIterator
32     {
33       /*!
34        * \brief A first type.
35        */
36       typedef char Small;
37       /*!
38        * \brief A Second type which size is higher than Small
39        */
40       struct Big{Small dummy[2];};
41       /*!
42        * \brief a substitute for classes that have only protected constructors
43        */
44       template<typename B>
45       struct Subs
46       {};
47 
48     protected:
49 
50       /*
51        * A Test fonction which returns a Small.
52        * Can only be called if B defines a const_iterator.
53        */
54       template<typename B>
55       static typename std::enable_if<
56 	sizeof(typename B::const_iterator)!=0,
57 	Small
58       >::type
59       Test(const Subs<B>);
60 
61       /*
62        * A Test fonction which returns a Big.
63        * It is called only if B does not defines a const_iterator.
64        */
65       static Big Test(...);
66 
67       /*!
68        * \brief A function returning a T.
69        * A small trick for classes that are not default constructible.
70        */
71       static Subs<A> MakeSubsA();
72 
73     public:
74 
75       /*
76        * The result of the metafunction.
77        */
78       static constexpr bool cond = sizeof(Test(MakeSubsA()))==sizeof(Small);
79 
80     };
81 
82   } // end of namespace meta
83 
84 } // end of namespace tfel
85 
86 #endif /* LIB_TFEL_HASCONSTITERATOR_HXX */
87 
88