1 // -*- mode: C++; c-indent-level: 4; c-basic-offset: 4; tab-width: 8 -*- 2 /* :tabSize=4:indentSize=4:noTabs=false:folding=explicit:collapseFolds=1: */ 3 // 4 // has_iterator.h: Rcpp R/C++ interface class library -- identify if a class has a nested iterator typedef 5 // 6 // Copyright (C) 2010 - 2011 Dirk Eddelbuettel and Romain Francois 7 // 8 // This file is part of Rcpp. 9 // 10 // Rcpp is free software: you can redistribute it and/or modify it 11 // under the terms of the GNU General Public License as published by 12 // the Free Software Foundation, either version 2 of the License, or 13 // (at your option) any later version. 14 // 15 // Rcpp is distributed in the hope that it will be useful, but 16 // WITHOUT ANY WARRANTY; without even the implied warranty of 17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 // GNU General Public License for more details. 19 // 20 // You should have received a copy of the GNU General Public License 21 // along with Rcpp. If not, see <http://www.gnu.org/licenses/>. 22 23 #ifndef Rcpp__traits__has_iterator__h 24 #define Rcpp__traits__has_iterator__h 25 26 /* "inspired" from the tr1_impl/functional file 27 This uses the SFINAE technique to identify if a class T has 28 an iterator typedef 29 */ 30 31 namespace Rcpp{ 32 namespace traits{ 33 34 struct __sfinae_types { 35 typedef char __one; 36 typedef struct { char __arr[2]; } __two; 37 }; 38 39 template<typename T> 40 class _has_iterator_helper : __sfinae_types { 41 template<typename U> struct _Wrap_type { }; 42 43 template<typename U> 44 static __one __test(_Wrap_type<typename U::iterator>*); 45 46 template<typename U> 47 static __two __test(...); 48 49 public: 50 static const bool value = sizeof(__test<T>(0)) == 1; 51 }; 52 53 template<typename T> 54 class _is_importer_helper : __sfinae_types { 55 template<typename U> struct _Wrap_type { }; 56 57 template<typename U> 58 static __one __test(_Wrap_type<typename U::r_import_type>*); 59 60 template<typename U> 61 static __two __test(...); 62 63 public: 64 static const bool value = sizeof(__test<T>(0)) == 1; 65 }; 66 67 template<typename T> 68 class _is_generator_helper : __sfinae_types { 69 template<typename U> struct _Wrap_type { }; 70 71 template<typename U> 72 static __one __test(_Wrap_type<typename U::r_generator>*); 73 74 template<typename U> 75 static __two __test(...); 76 77 public: 78 static const bool value = sizeof(__test<T>(0)) == 1; 79 }; 80 81 82 template<typename T> 83 class _is_exporter_helper : __sfinae_types { 84 template<typename U> struct _Wrap_type { }; 85 86 template<typename U> 87 static __one __test(_Wrap_type<typename U::r_export_type>*); 88 89 template<typename U> 90 static __two __test(...); 91 92 public: 93 static const bool value = sizeof(__test<T>(0)) == 1; 94 }; 95 96 /** 97 * uses the SFINAE idiom to check if a class has an 98 * nested iterator typedef. For example : 99 * 100 * has_iterator< std::vector<int> >::value is true 101 * has_iterator< Rcpp::Symbol >::value is false 102 */ 103 template<typename T> struct has_iterator : 104 integral_constant<bool,_has_iterator_helper<T>::value> { }; 105 106 /** 107 * uses SFINAE to identify if a type is importable 108 * 109 * The test is based on the presence of a typedef r_import_type in the 110 * class 111 */ 112 template<typename T> struct is_importer : 113 integral_constant<bool,_is_importer_helper<T>::value> { }; 114 115 template<typename T> struct is_exporter : 116 integral_constant<bool,_is_exporter_helper<T>::value> { }; 117 118 template<typename T> struct is_generator : 119 integral_constant<bool,_is_generator_helper<T>::value> { }; 120 121 } // traits 122 } // Rcpp 123 124 #endif 125