source: NonGTP/Boost/boost/regex/v4/basic_regex.hpp @ 857

Revision 857, 19.1 KB checked in by igarcia, 18 years ago (diff)
Line 
1/*
2 *
3 * Copyright (c) 1998-2004
4 * John Maddock
5 *
6 * Use, modification and distribution are subject to the
7 * Boost Software License, Version 1.0. (See accompanying file
8 * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
9 *
10 */
11
12 /*
13  *   LOCATION:    see http://www.boost.org for most recent version.
14  *   FILE         basic_regex.cpp
15  *   VERSION      see <boost/version.hpp>
16  *   DESCRIPTION: Declares template class basic_regex.
17  */
18
19#ifndef BOOST_REGEX_V4_BASIC_REGEX_HPP
20#define BOOST_REGEX_V4_BASIC_REGEX_HPP
21
22#ifdef BOOST_HAS_ABI_HEADERS
23#  include BOOST_ABI_PREFIX
24#endif
25
26namespace boost{
27#ifdef BOOST_MSVC
28#pragma warning(push)
29#pragma warning(disable : 4251 4231 4660)
30#endif
31
32namespace re_detail{
33
34//
35// forward declaration, we will need this one later:
36//
37template <class charT, class traits>
38class basic_regex_parser;
39
40//
41// class regex_data:
42// represents the data we wish to expose to the matching algorithms.
43//
44template <class charT, class traits>
45struct regex_data
46{
47   typedef regex_constants::syntax_option_type   flag_type;
48   typedef std::size_t                           size_type; 
49
50   regex_data(const ::boost::shared_ptr<
51      ::boost::regex_traits_wrapper<traits> >& t)
52      : m_ptraits(t), m_expression(0), m_expression_len(0) {}
53   regex_data()
54      : m_ptraits(new ::boost::regex_traits_wrapper<traits>()), m_expression(0), m_expression_len(0) {}
55
56   ::boost::shared_ptr<
57      ::boost::regex_traits_wrapper<traits>
58      >                        m_ptraits;                 // traits class instance
59   flag_type                   m_flags;                   // flags with which we were compiled
60   int                         m_status;                  // error code (0 implies OK).
61   const charT*                m_expression;              // the original expression
62   std::ptrdiff_t              m_expression_len;          // the length of the original expression
63   size_type                   m_mark_count;              // the number of marked sub-expressions
64   re_detail::re_syntax_base*  m_first_state;             // the first state of the machine
65   unsigned                    m_restart_type;            // search optimisation type
66   unsigned char               m_startmap[1 << CHAR_BIT]; // which characters can start a match
67   unsigned int                m_can_be_null;             // whether we can match a null string
68   re_detail::raw_storage      m_data;                    // the buffer in which our states are constructed
69};
70//
71// class basic_regex_implementation
72// pimpl implementation class for basic_regex.
73//
74template <class charT, class traits>
75class basic_regex_implementation
76   : public regex_data<charT, traits>
77{
78public:
79   typedef regex_constants::syntax_option_type   flag_type;
80   typedef std::ptrdiff_t                        difference_type;
81   typedef std::size_t                           size_type;
82   typedef typename traits::locale_type          locale_type;
83   typedef const charT*                          const_iterator;
84
85   basic_regex_implementation(){}
86   basic_regex_implementation(const ::boost::shared_ptr<
87      ::boost::regex_traits_wrapper<traits> >& t)
88      : regex_data<charT, traits>(t) {}
89   void assign(const charT* arg_first,
90                          const charT* arg_last,
91                          flag_type f)
92   {
93      regex_data<charT, traits>* pdat = this;
94      basic_regex_parser<charT, traits> parser(pdat);
95      parser.parse(arg_first, arg_last, f);
96   }
97
98   locale_type BOOST_REGEX_CALL imbue(locale_type l)
99   {
100      return this->m_ptraits->imbue(l);
101   }
102   locale_type BOOST_REGEX_CALL getloc()const
103   {
104      return this->m_ptraits->getloc();
105   }
106   std::basic_string<charT> BOOST_REGEX_CALL str()const
107   {
108      std::basic_string<charT> result;
109      if(this->m_status == 0)
110         result = std::basic_string<charT>(this->m_expression, this->m_expression_len);
111      return result;
112   }
113   const_iterator BOOST_REGEX_CALL expression()const
114   {
115      return this->m_expression;
116   }
117   //
118   // begin, end:
119   const_iterator BOOST_REGEX_CALL begin()const
120   {
121      return (!this->m_status ? 0 : this->m_expression);
122   }
123   const_iterator BOOST_REGEX_CALL end()const
124   {
125      return (!this->m_status ? 0 : this->m_expression + this->m_expression_len);
126   }
127   flag_type BOOST_REGEX_CALL flags()const
128   {
129      return this->m_flags;
130   }
131   size_type BOOST_REGEX_CALL size()const
132   {
133      return this->m_expression_len;
134   }
135   int BOOST_REGEX_CALL status()const
136   {
137      return this->m_status;
138   }
139   size_type BOOST_REGEX_CALL mark_count()const
140   {
141      return this->m_mark_count;
142   }
143   const re_detail::re_syntax_base* get_first_state()const
144   {
145      return this->m_first_state;
146   }
147   unsigned get_restart_type()const
148   {
149      return this->m_restart_type;
150   }
151   const unsigned char* get_map()const
152   {
153      return this->m_startmap;
154   }
155   const ::boost::regex_traits_wrapper<traits>& get_traits()const
156   {
157      return *(this->m_ptraits);
158   }
159   bool can_be_null()const
160   {
161      return this->m_can_be_null;
162   }
163   const regex_data<charT, traits>& get_data()const
164   {
165      basic_regex_implementation<charT, traits> const* p = this;
166      return *static_cast<const regex_data<charT, traits>*>(p);
167   }
168};
169
170} // namespace re_detail
171//
172// class basic_regex:
173// represents the compiled
174// regular expression:
175//
176
177#ifdef BOOST_REGEX_NO_FWD
178template <class charT, class traits = regex_traits<charT> >
179#else
180template <class charT, class traits >
181#endif
182class basic_regex : public regbase
183{
184public:
185   // typedefs:
186   typedef typename traits::size_type            traits_size_type;
187   typedef typename traits::string_type          traits_string_type;
188   typedef charT                                 char_type;
189   typedef traits                                traits_type;
190
191   typedef charT                                 value_type;
192   typedef charT&                                reference;
193   typedef const charT&                          const_reference;
194   typedef const charT*                          const_iterator;
195   typedef const_iterator                        iterator;
196   typedef std::ptrdiff_t                        difference_type;
197   typedef std::size_t                           size_type;   
198   typedef regex_constants::syntax_option_type   flag_type;
199   // locale_type
200   // placeholder for actual locale type used by the
201   // traits class to localise *this.
202   typedef typename traits::locale_type          locale_type;
203   
204public:
205   explicit basic_regex(){}
206   explicit basic_regex(const charT* p, flag_type f = regex_constants::normal)
207   {
208      assign(p, f);
209   }
210   basic_regex(const charT* p1, const charT* p2, flag_type f = regex_constants::normal)
211   {
212      assign(p1, p2, f);
213   }
214   basic_regex(const charT* p, size_type len, flag_type f)
215   {
216      assign(p, len, f);
217   }
218   basic_regex(const basic_regex& that)
219      : m_pimpl(that.m_pimpl) {}
220   ~basic_regex(){}
221   basic_regex& BOOST_REGEX_CALL operator=(const basic_regex& that)
222   {
223      return assign(that);
224   }
225   basic_regex& BOOST_REGEX_CALL operator=(const charT* ptr)
226   {
227      return assign(ptr);
228   }
229
230   //
231   // assign:
232   basic_regex& assign(const basic_regex& that)
233   {
234      m_pimpl = that.m_pimpl;
235      return *this;
236   }
237   basic_regex& assign(const charT* p, flag_type f = regex_constants::normal)
238   {
239      return assign(p, p + traits::length(p), f);
240   }
241   basic_regex& assign(const charT* p, size_type len, flag_type f)
242   {
243      return assign(p, p + len, f);
244   }
245private:
246   basic_regex& do_assign(const charT* p1,
247                          const charT* p2,
248                          flag_type f);
249public:
250   basic_regex& assign(const charT* p1,
251                          const charT* p2,
252                          flag_type f = regex_constants::normal)
253   {
254      return do_assign(p1, p2, f);
255   }
256#if !defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(__IBMCPP__)
257
258   template <class ST, class SA>
259   unsigned int BOOST_REGEX_CALL set_expression(const std::basic_string<charT, ST, SA>& p, flag_type f = regex_constants::normal)
260   {
261      return set_expression(p.data(), p.data() + p.size(), f);
262   }
263
264   template <class ST, class SA>
265   explicit basic_regex(const std::basic_string<charT, ST, SA>& p, flag_type f = regex_constants::normal)
266   {
267      assign(p, f);
268   }
269
270   template <class InputIterator>
271   basic_regex(InputIterator arg_first, InputIterator arg_last, flag_type f = regex_constants::normal)
272   {
273      typedef typename traits::string_type seq_type;
274      seq_type a(arg_first, arg_last);
275      if(a.size())
276         assign(&*a.begin(), &*a.begin() + a.size(), f);
277      else
278         assign(static_cast<const charT*>(0), static_cast<const charT*>(0), f);
279   }
280
281   template <class ST, class SA>
282   basic_regex& BOOST_REGEX_CALL operator=(const std::basic_string<charT, ST, SA>& p)
283   {
284      return assign(p.data(), p.data() + p.size(), regex_constants::normal);
285   }
286
287   template <class string_traits, class A>
288   basic_regex& BOOST_REGEX_CALL assign(
289       const std::basic_string<charT, string_traits, A>& s,
290       flag_type f = regex_constants::normal)
291   {
292      return assign(s.data(), s.data() + s.size(), f);
293   }
294
295   template <class InputIterator>
296   basic_regex& BOOST_REGEX_CALL assign(InputIterator arg_first,
297                          InputIterator arg_last,
298                          flag_type f = regex_constants::normal)
299   {
300      typedef typename traits::string_type seq_type;
301      seq_type a(arg_first, arg_last);
302      if(a.size())
303      {
304         const charT* p1 = &*a.begin();
305         const charT* p2 = &*a.begin() + a.size();
306         return assign(p1, p2, f);
307      }
308      return assign(static_cast<const charT*>(0), static_cast<const charT*>(0), f);
309   }
310#else
311   unsigned int BOOST_REGEX_CALL set_expression(const std::basic_string<charT>& p, flag_type f = regex_constants::normal)
312   {
313      return set_expression(p.data(), p.data() + p.size(), f);
314   }
315
316   basic_regex(const std::basic_string<charT>& p, flag_type f = regex_constants::normal)
317   {
318      assign(p, f);
319   }
320
321   basic_regex& BOOST_REGEX_CALL operator=(const std::basic_string<charT>& p)
322   {
323      return assign(p.data(), p.data() + p.size(), regex_constants::normal);
324   }
325
326   basic_regex& BOOST_REGEX_CALL assign(
327       const std::basic_string<charT>& s,
328       flag_type f = regex_constants::normal)
329   {
330      return assign(s.data(), s.data() + s.size(), f);
331   }
332
333#endif
334
335   //
336   // locale:
337   locale_type BOOST_REGEX_CALL imbue(locale_type l);
338   locale_type BOOST_REGEX_CALL getloc()const
339   {
340      return m_pimpl.get() ? m_pimpl->getloc() : locale_type();
341   }
342   //
343   // getflags:
344   // retained for backwards compatibility only, "flags"
345   // is now the prefered name:
346   flag_type BOOST_REGEX_CALL getflags()const
347   {
348      return flags();
349   }
350   flag_type BOOST_REGEX_CALL flags()const
351   {
352      return m_pimpl.get() ? m_pimpl->flags() : 0;
353   }
354   //
355   // str:
356   std::basic_string<charT> BOOST_REGEX_CALL str()const
357   {
358      return m_pimpl.get() ? m_pimpl->str() : std::basic_string<charT>();
359   }
360   //
361   // begin, end:
362   const_iterator BOOST_REGEX_CALL begin()const
363   {
364      return (m_pimpl.get() ? m_pimpl->begin() : 0);
365   }
366   const_iterator BOOST_REGEX_CALL end()const
367   {
368      return (m_pimpl.get() ? m_pimpl->end() : 0);
369   }
370   //
371   // swap:
372   void BOOST_REGEX_CALL swap(basic_regex& that)throw()
373   {
374      m_pimpl.swap(that.m_pimpl);
375   }
376   //
377   // size:
378   size_type BOOST_REGEX_CALL size()const
379   {
380      return (m_pimpl.get() ? m_pimpl->size() : 0);
381   }
382   //
383   // max_size:
384   size_type BOOST_REGEX_CALL max_size()const
385   {
386      return UINT_MAX;
387   }
388   //
389   // empty:
390   bool BOOST_REGEX_CALL empty()const
391   {
392      return (m_pimpl.get() ? 0 != m_pimpl->status() : true);
393   }
394
395   size_type BOOST_REGEX_CALL mark_count()const
396   {
397      return (m_pimpl.get() ? m_pimpl->mark_count() : 0);
398   }
399
400   int status()const
401   {
402      return (m_pimpl.get() ? m_pimpl->status() : regex_constants::error_empty);
403   }
404
405   int BOOST_REGEX_CALL compare(const basic_regex& that) const
406   {
407      if(m_pimpl.get() == that.m_pimpl.get())
408         return 0;
409      if(!m_pimpl.get())
410         return -1;
411      if(!that.m_pimpl.get())
412         return 1;
413      if(status() != that.status())
414         return status() - that.status();
415      if(flags() != that.flags())
416         return flags() - that.flags();
417      return str().compare(that.str());
418   }
419   bool BOOST_REGEX_CALL operator==(const basic_regex& e)const
420   {
421      return compare(e) == 0;
422   }
423   bool BOOST_REGEX_CALL operator != (const basic_regex& e)const
424   {
425      return compare(e) != 0;
426   }
427   bool BOOST_REGEX_CALL operator<(const basic_regex& e)const
428   {
429      return compare(e) < 0;
430   }
431   bool BOOST_REGEX_CALL operator>(const basic_regex& e)const
432   {
433      return compare(e) > 0;
434   }
435   bool BOOST_REGEX_CALL operator<=(const basic_regex& e)const
436   {
437      return compare(e) <= 0;
438   }
439   bool BOOST_REGEX_CALL operator>=(const basic_regex& e)const
440   {
441      return compare(e) >= 0;
442   }
443
444   //
445   // The following are deprecated as public interfaces
446   // but are available for compatibility with earlier versions.
447   const charT* BOOST_REGEX_CALL expression()const
448   {
449      return (m_pimpl.get() && !m_pimpl->status() ? m_pimpl->expression() : 0);
450   }
451   unsigned int BOOST_REGEX_CALL set_expression(const charT* p1, const charT* p2, flag_type f = regex_constants::normal)
452   {
453      assign(p1, p2, f | regex_constants::no_except);
454      return status();
455   }
456   unsigned int BOOST_REGEX_CALL set_expression(const charT* p, flag_type f = regex_constants::normal)
457   {
458      assign(p, f | regex_constants::no_except);
459      return status();
460   }
461   unsigned int BOOST_REGEX_CALL error_code()const
462   {
463      return status();
464   }
465   //
466   // private access methods:
467   //
468   const re_detail::re_syntax_base* get_first_state()const
469   {
470      BOOST_ASSERT(0 != m_pimpl.get());
471      return m_pimpl->get_first_state();
472   }
473   unsigned get_restart_type()const
474   {
475      BOOST_ASSERT(0 != m_pimpl.get());
476      return m_pimpl->get_restart_type();
477   }
478   const unsigned char* get_map()const
479   {
480      BOOST_ASSERT(0 != m_pimpl.get());
481      return m_pimpl->get_map();
482   }
483   const ::boost::regex_traits_wrapper<traits>& get_traits()const
484   {
485      BOOST_ASSERT(0 != m_pimpl.get());
486      return m_pimpl->get_traits();
487   }
488   bool can_be_null()const
489   {
490      BOOST_ASSERT(0 != m_pimpl.get());
491      return m_pimpl->can_be_null();
492   }
493   const re_detail::regex_data<charT, traits>& get_data()const
494   {
495      BOOST_ASSERT(0 != m_pimpl.get());
496      return m_pimpl->get_data();
497   }
498
499private:
500   shared_ptr<re_detail::basic_regex_implementation<charT, traits> > m_pimpl;
501};
502
503//
504// out of line members;
505// these are the only members that mutate the basic_regex object,
506// and are designed to provide the strong exception guarentee
507// (in the event of a throw, the state of the object remains unchanged).
508//
509template <class charT, class traits>
510basic_regex<charT, traits>& basic_regex<charT, traits>::do_assign(const charT* p1,
511                        const charT* p2,
512                        flag_type f)
513{
514   shared_ptr<re_detail::basic_regex_implementation<charT, traits> > temp;
515   if(!m_pimpl.get())
516   {
517      temp = shared_ptr<re_detail::basic_regex_implementation<charT, traits> >(new re_detail::basic_regex_implementation<charT, traits>());
518   }
519   else
520   {
521      temp = shared_ptr<re_detail::basic_regex_implementation<charT, traits> >(new re_detail::basic_regex_implementation<charT, traits>(m_pimpl->m_ptraits));
522   }
523   temp->assign(p1, p2, f);
524   temp.swap(m_pimpl);
525   return *this;
526}
527
528template <class charT, class traits>
529typename basic_regex<charT, traits>::locale_type BOOST_REGEX_CALL basic_regex<charT, traits>::imbue(locale_type l)
530{
531   shared_ptr<re_detail::basic_regex_implementation<charT, traits> > temp(new re_detail::basic_regex_implementation<charT, traits>());
532   locale_type result = temp->imbue(l);
533   temp.swap(m_pimpl);
534   return result;
535}
536
537//
538// non-members:
539//
540template <class charT, class traits>
541void swap(basic_regex<charT, traits>& e1, basic_regex<charT, traits>& e2)
542{
543   e1.swap(e2);
544}
545
546#ifndef BOOST_NO_STD_LOCALE
547template <class charT, class traits, class traits2>
548std::basic_ostream<charT, traits>&
549   operator << (std::basic_ostream<charT, traits>& os,
550                const basic_regex<charT, traits2>& e)
551{
552   return (os << e.str());
553}
554#else
555template <class traits>
556std::ostream& operator << (std::ostream& os, const basic_regex<char, traits>& e)
557{
558   return (os << e.str());
559}
560#endif
561
562//
563// class reg_expression:
564// this is provided for backwards compatibility only,
565// it is deprecated, no not use!
566//
567#ifdef BOOST_REGEX_NO_FWD
568template <class charT, class traits = regex_traits<charT> >
569#else
570template <class charT, class traits >
571#endif
572class reg_expression : public basic_regex<charT, traits>
573{
574public:
575   typedef typename basic_regex<charT, traits>::flag_type flag_type;
576   typedef typename basic_regex<charT, traits>::size_type size_type;
577   explicit reg_expression(){}
578   explicit reg_expression(const charT* p, flag_type f = regex_constants::normal)
579      : basic_regex<charT, traits>(p, f){}
580   reg_expression(const charT* p1, const charT* p2, flag_type f = regex_constants::normal)
581      : basic_regex<charT, traits>(p1, p2, f){}
582   reg_expression(const charT* p, size_type len, flag_type f)
583      : basic_regex<charT, traits>(p, len, f){}
584   reg_expression(const reg_expression& that)
585      : basic_regex<charT, traits>(that) {}
586   ~reg_expression(){}
587   reg_expression& BOOST_REGEX_CALL operator=(const reg_expression& that)
588   {
589      return this->assign(that);
590   }
591
592#if !defined(BOOST_NO_MEMBER_TEMPLATES) && !defined(__IBMCPP__)
593   template <class ST, class SA>
594   explicit reg_expression(const std::basic_string<charT, ST, SA>& p, flag_type f = regex_constants::normal)
595   : basic_regex<charT, traits>(p, f)
596   {
597   }
598
599   template <class InputIterator>
600   reg_expression(InputIterator arg_first, InputIterator arg_last, flag_type f = regex_constants::normal)
601   : basic_regex<charT, traits>(arg_first, arg_last, f)
602   {
603   }
604
605   template <class ST, class SA>
606   reg_expression& BOOST_REGEX_CALL operator=(const std::basic_string<charT, ST, SA>& p)
607   {
608      this->assign(p);
609      return *this;
610   }
611#else
612   explicit reg_expression(const std::basic_string<charT>& p, flag_type f = regex_constants::normal)
613   : basic_regex<charT, traits>(p, f)
614   {
615   }
616
617   reg_expression& BOOST_REGEX_CALL operator=(const std::basic_string<charT>& p)
618   {
619      this->assign(p);
620      return *this;
621   }
622#endif
623
624};
625
626#ifdef BOOST_MSVC
627#pragma warning (pop)
628#endif
629
630} // namespace boost
631
632#ifdef BOOST_HAS_ABI_HEADERS
633#  include BOOST_ABI_SUFFIX
634#endif
635
636#endif
637
Note: See TracBrowser for help on using the repository browser.