classification.hpp 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354
  1. // Boost string_algo library classification.hpp header file ---------------------------//
  2. // Copyright Pavol Droba 2002-2003.
  3. //
  4. // Distributed under the Boost Software License, Version 1.0.
  5. // (See accompanying file LICENSE_1_0.txt or copy at
  6. // http://www.boost.org/LICENSE_1_0.txt)
  7. // See http://www.boost.org/ for updates, documentation, and revision history.
  8. #ifndef BOOST_STRING_CLASSIFICATION_DETAIL_HPP
  9. #define BOOST_STRING_CLASSIFICATION_DETAIL_HPP
  10. #include <boost/algorithm/string/config.hpp>
  11. #include <algorithm>
  12. #include <functional>
  13. #include <locale>
  14. #include <boost/range/begin.hpp>
  15. #include <boost/range/end.hpp>
  16. #include <boost/algorithm/string/predicate_facade.hpp>
  17. #include <boost/type_traits/remove_const.hpp>
  18. namespace boost {
  19. namespace algorithm {
  20. namespace detail {
  21. // classification functors -----------------------------------------------//
  22. // is_classified functor
  23. struct is_classifiedF :
  24. public predicate_facade<is_classifiedF>
  25. {
  26. // Boost.ResultOf support
  27. typedef bool result_type;
  28. // Constructor from a locale
  29. is_classifiedF(std::ctype_base::mask Type, std::locale const & Loc = std::locale()) :
  30. m_Type(Type), m_Locale(Loc) {}
  31. // Operation
  32. template<typename CharT>
  33. bool operator()( CharT Ch ) const
  34. {
  35. return std::use_facet< std::ctype<CharT> >(m_Locale).is( m_Type, Ch );
  36. }
  37. #if defined(__BORLANDC__) && (__BORLANDC__ >= 0x560) && (__BORLANDC__ <= 0x582) && !defined(_USE_OLD_RW_STL)
  38. template<>
  39. bool operator()( char const Ch ) const
  40. {
  41. return std::use_facet< std::ctype<char> >(m_Locale).is( m_Type, Ch );
  42. }
  43. #endif
  44. private:
  45. std::ctype_base::mask m_Type;
  46. std::locale m_Locale;
  47. };
  48. // is_any_of functor
  49. /*
  50. returns true if the value is from the specified set
  51. */
  52. template<typename CharT>
  53. struct is_any_ofF :
  54. public predicate_facade<is_any_ofF<CharT> >
  55. {
  56. private:
  57. // set cannot operate on const value-type
  58. typedef typename ::boost::remove_const<CharT>::type set_value_type;
  59. public:
  60. // Boost.ResultOf support
  61. typedef bool result_type;
  62. // Constructor
  63. template<typename RangeT>
  64. is_any_ofF( const RangeT& Range ) : m_Size(0)
  65. {
  66. // Prepare storage
  67. m_Storage.m_dynSet=0;
  68. std::size_t Size=::boost::distance(Range);
  69. m_Size=Size;
  70. set_value_type* Storage=0;
  71. if(use_fixed_storage(m_Size))
  72. {
  73. // Use fixed storage
  74. Storage=&m_Storage.m_fixSet[0];
  75. }
  76. else
  77. {
  78. // Use dynamic storage
  79. m_Storage.m_dynSet=new set_value_type[m_Size];
  80. Storage=m_Storage.m_dynSet;
  81. }
  82. // Use fixed storage
  83. ::std::copy(::boost::begin(Range), ::boost::end(Range), Storage);
  84. ::std::sort(Storage, Storage+m_Size);
  85. }
  86. // Copy constructor
  87. is_any_ofF(const is_any_ofF& Other) : m_Size(Other.m_Size)
  88. {
  89. // Prepare storage
  90. m_Storage.m_dynSet=0;
  91. const set_value_type* SrcStorage=0;
  92. set_value_type* DestStorage=0;
  93. if(use_fixed_storage(m_Size))
  94. {
  95. // Use fixed storage
  96. DestStorage=&m_Storage.m_fixSet[0];
  97. SrcStorage=&Other.m_Storage.m_fixSet[0];
  98. }
  99. else
  100. {
  101. // Use dynamic storage
  102. m_Storage.m_dynSet=new set_value_type[m_Size];
  103. DestStorage=m_Storage.m_dynSet;
  104. SrcStorage=Other.m_Storage.m_dynSet;
  105. }
  106. // Use fixed storage
  107. ::std::memcpy(DestStorage, SrcStorage, sizeof(set_value_type)*m_Size);
  108. }
  109. // Destructor
  110. ~is_any_ofF()
  111. {
  112. if(!use_fixed_storage(m_Size) && m_Storage.m_dynSet!=0)
  113. {
  114. delete [] m_Storage.m_dynSet;
  115. }
  116. }
  117. // Assignment
  118. is_any_ofF& operator=(const is_any_ofF& Other)
  119. {
  120. // Handle self assignment
  121. if(this==&Other) return *this;
  122. // Prepare storage
  123. const set_value_type* SrcStorage;
  124. set_value_type* DestStorage;
  125. if(use_fixed_storage(Other.m_Size))
  126. {
  127. // Use fixed storage
  128. DestStorage=&m_Storage.m_fixSet[0];
  129. SrcStorage=&Other.m_Storage.m_fixSet[0];
  130. // Delete old storage if was present
  131. if(!use_fixed_storage(m_Size) && m_Storage.m_dynSet!=0)
  132. {
  133. delete [] m_Storage.m_dynSet;
  134. }
  135. // Set new size
  136. m_Size=Other.m_Size;
  137. }
  138. else
  139. {
  140. // Other uses dynamic storage
  141. SrcStorage=Other.m_Storage.m_dynSet;
  142. // Check what kind of storage are we using right now
  143. if(use_fixed_storage(m_Size))
  144. {
  145. // Using fixed storage, allocate new
  146. set_value_type* pTemp=new set_value_type[Other.m_Size];
  147. DestStorage=pTemp;
  148. m_Storage.m_dynSet=pTemp;
  149. m_Size=Other.m_Size;
  150. }
  151. else
  152. {
  153. // Using dynamic storage, check if can reuse
  154. if(m_Storage.m_dynSet!=0 && m_Size>=Other.m_Size && m_Size<Other.m_Size*2)
  155. {
  156. // Reuse the current storage
  157. DestStorage=m_Storage.m_dynSet;
  158. m_Size=Other.m_Size;
  159. }
  160. else
  161. {
  162. // Allocate the new one
  163. set_value_type* pTemp=new set_value_type[Other.m_Size];
  164. DestStorage=pTemp;
  165. // Delete old storage if necessary
  166. if(m_Storage.m_dynSet!=0)
  167. {
  168. delete [] m_Storage.m_dynSet;
  169. }
  170. // Store the new storage
  171. m_Storage.m_dynSet=pTemp;
  172. // Set new size
  173. m_Size=Other.m_Size;
  174. }
  175. }
  176. }
  177. // Copy the data
  178. ::std::memcpy(DestStorage, SrcStorage, sizeof(set_value_type)*m_Size);
  179. return *this;
  180. }
  181. // Operation
  182. template<typename Char2T>
  183. bool operator()( Char2T Ch ) const
  184. {
  185. const set_value_type* Storage=
  186. (use_fixed_storage(m_Size))
  187. ? &m_Storage.m_fixSet[0]
  188. : m_Storage.m_dynSet;
  189. return ::std::binary_search(Storage, Storage+m_Size, Ch);
  190. }
  191. private:
  192. // check if the size is eligible for fixed storage
  193. static bool use_fixed_storage(std::size_t size)
  194. {
  195. return size<=sizeof(set_value_type*)*2;
  196. }
  197. private:
  198. // storage
  199. // The actual used storage is selected on the type
  200. union
  201. {
  202. set_value_type* m_dynSet;
  203. set_value_type m_fixSet[sizeof(set_value_type*)*2];
  204. }
  205. m_Storage;
  206. // storage size
  207. ::std::size_t m_Size;
  208. };
  209. // is_from_range functor
  210. /*
  211. returns true if the value is from the specified range.
  212. (i.e. x>=From && x>=To)
  213. */
  214. template<typename CharT>
  215. struct is_from_rangeF :
  216. public predicate_facade< is_from_rangeF<CharT> >
  217. {
  218. // Boost.ResultOf support
  219. typedef bool result_type;
  220. // Constructor
  221. is_from_rangeF( CharT From, CharT To ) : m_From(From), m_To(To) {}
  222. // Operation
  223. template<typename Char2T>
  224. bool operator()( Char2T Ch ) const
  225. {
  226. return ( m_From <= Ch ) && ( Ch <= m_To );
  227. }
  228. private:
  229. CharT m_From;
  230. CharT m_To;
  231. };
  232. // class_and composition predicate
  233. template<typename Pred1T, typename Pred2T>
  234. struct pred_andF :
  235. public predicate_facade< pred_andF<Pred1T,Pred2T> >
  236. {
  237. public:
  238. // Boost.ResultOf support
  239. typedef bool result_type;
  240. // Constructor
  241. pred_andF( Pred1T Pred1, Pred2T Pred2 ) :
  242. m_Pred1(Pred1), m_Pred2(Pred2) {}
  243. // Operation
  244. template<typename CharT>
  245. bool operator()( CharT Ch ) const
  246. {
  247. return m_Pred1(Ch) && m_Pred2(Ch);
  248. }
  249. private:
  250. Pred1T m_Pred1;
  251. Pred2T m_Pred2;
  252. };
  253. // class_or composition predicate
  254. template<typename Pred1T, typename Pred2T>
  255. struct pred_orF :
  256. public predicate_facade< pred_orF<Pred1T,Pred2T> >
  257. {
  258. public:
  259. // Boost.ResultOf support
  260. typedef bool result_type;
  261. // Constructor
  262. pred_orF( Pred1T Pred1, Pred2T Pred2 ) :
  263. m_Pred1(Pred1), m_Pred2(Pred2) {}
  264. // Operation
  265. template<typename CharT>
  266. bool operator()( CharT Ch ) const
  267. {
  268. return m_Pred1(Ch) || m_Pred2(Ch);
  269. }
  270. private:
  271. Pred1T m_Pred1;
  272. Pred2T m_Pred2;
  273. };
  274. // class_not composition predicate
  275. template< typename PredT >
  276. struct pred_notF :
  277. public predicate_facade< pred_notF<PredT> >
  278. {
  279. public:
  280. // Boost.ResultOf support
  281. typedef bool result_type;
  282. // Constructor
  283. pred_notF( PredT Pred ) : m_Pred(Pred) {}
  284. // Operation
  285. template<typename CharT>
  286. bool operator()( CharT Ch ) const
  287. {
  288. return !m_Pred(Ch);
  289. }
  290. private:
  291. PredT m_Pred;
  292. };
  293. } // namespace detail
  294. } // namespace algorithm
  295. } // namespace boost
  296. #endif // BOOST_STRING_CLASSIFICATION_DETAIL_HPP