classification.hpp 12 KB

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