source: NonGTP/Boost/boost/test/utils/basic_cstring/basic_cstring.hpp @ 857

Revision 857, 22.6 KB checked in by igarcia, 18 years ago (diff)
Line 
1//  (C) Copyright Gennadiy Rozental 2004-2005.
2//  Distributed under the Boost Software License, Version 1.0.
3//  (See accompanying file LICENSE_1_0.txt or copy at
4//  http://www.boost.org/LICENSE_1_0.txt)
5
6//  See http://www.boost.org/libs/test for the library home page.
7//
8//  File        : $RCSfile: basic_cstring.hpp,v $
9//
10//  Version     : $Revision: 1.9 $
11//
12//  Description : class basic_cstring wraps C string and provide std_string like
13//                interface
14// ***************************************************************************
15
16#ifndef BOOST_TEST_BASIC_CSTRING_HPP_071894GER
17#define BOOST_TEST_BASIC_CSTRING_HPP_071894GER
18
19// Boost.Test
20#include <boost/test/utils/basic_cstring/basic_cstring_fwd.hpp>
21#include <boost/test/utils/basic_cstring/bcs_char_traits.hpp>
22
23// STL
24#include <string>
25
26#include <boost/test/detail/suppress_warnings.hpp>
27
28//____________________________________________________________________________//
29
30namespace boost {
31
32namespace unit_test {
33
34// ************************************************************************** //
35// **************                basic_cstring                 ************** //
36// ************************************************************************** //
37
38template<typename CharT>
39class basic_cstring {
40    typedef basic_cstring<CharT>                        self_type;
41public:
42    // Subtypes
43    typedef ut_detail::bcs_char_traits<CharT>           traits_type;
44    typedef typename ut_detail::bcs_char_traits<CharT>::std_string  std_string;
45
46    typedef CharT                                       value_type;
47    typedef value_type*                                 pointer;
48    typedef value_type const*                           const_pointer;
49    typedef value_type&                                 reference;
50    typedef const value_type&                           const_reference;
51    typedef std::size_t                                 size_type;
52    typedef std::ptrdiff_t                              difference_type;
53
54    typedef value_type const*                           const_iterator;
55    typedef value_type*                                 iterator;
56
57    //!! should also present reverse_iterator, const_reverse_iterator
58
59#if !BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600))
60    enum npos_type { npos = (size_type)-1 };
61#else
62    // IBM/VisualAge version 6 is not able to handle enums larger than 4 bytes.
63    // But size_type is 8 bytes in 64bit mode.
64    static const size_type npos = -1 ;
65#endif
66
67    static pointer  null_str();
68
69    // Constructors; default copy constructor is generated by compiler
70    basic_cstring();
71    basic_cstring( std_string const& s );
72    basic_cstring( pointer s );
73    basic_cstring( pointer s, size_type arg_size );
74    basic_cstring( pointer first, pointer last );
75
76    // data access methods
77    value_type      operator[]( size_type index ) const;
78    value_type      at( size_type index ) const;
79
80    // size operators
81    size_type       size() const;
82    bool            is_empty() const;
83    void            clear();
84    void            resize( size_type new_len );
85
86    //!! only for STL container conformance use is_empty instead
87    bool            empty() const;
88
89    // Trimming
90    self_type&      trim_right( size_type trim_size );
91    self_type&      trim_left( size_type trim_size );
92    self_type&      trim_right( iterator it );
93    self_type&      trim_left( iterator it );
94#ifndef __IBMCPP__
95    self_type&      trim_left( self_type exclusions = self_type() ) ;
96    self_type&      trim_right( self_type exclusions = self_type() ) ;
97    self_type&      trim( self_type exclusions = self_type() ) ;
98#else
99    // VisualAge version 6 has in this case a problem with the default arguments.
100    self_type&      trim_left( self_type exclusions ) ;
101    self_type&      trim_right( self_type exclusions ) ;
102    self_type&      trim( self_type exclusions ) ;
103    self_type&      trim_left() { trim_left( self_type() ) ; }
104    self_type&      trim_right() { trim_right( self_type() ) ; }
105    self_type&      trim() { trim( self_type() ) ; }
106#endif
107
108    // Assignment operators
109    basic_cstring&  operator=( self_type const& s );
110    basic_cstring&  operator=( std_string const& s );
111    basic_cstring&  operator=( pointer s );
112
113    template<typename CharT2>
114    basic_cstring&  assign( basic_cstring<CharT2> const& s ) { *this = basic_cstring<CharT>( s.begin(), s.end() ); return *this; }
115    basic_cstring&  assign( self_type const& s, size_type pos, size_type len );
116    basic_cstring&  assign( std_string const& s );
117    basic_cstring&  assign( std_string const& s, size_type pos, size_type len );
118    basic_cstring&  assign( pointer s );
119    basic_cstring&  assign( pointer s, size_type len );
120    basic_cstring&  assign( pointer f, pointer l );
121
122    // swapping
123    void            swap( self_type& s );
124
125    // Iterators
126    iterator        begin();
127    const_iterator  begin() const;
128    iterator        end();
129    const_iterator  end() const;
130
131    //!! should have rbegin, rend
132
133    // substring search operation
134    size_type       find( basic_cstring ) const;
135    size_type       rfind( basic_cstring ) const;
136    self_type       substr( size_type beg_index, size_type end_index = npos ) const;
137
138private:
139    static self_type default_trim_ex();
140
141    // Data members
142    iterator        m_begin;
143    iterator        m_end;
144};
145
146//____________________________________________________________________________//
147
148template<typename CharT>
149inline typename basic_cstring<CharT>::pointer
150basic_cstring<CharT>::null_str()
151{
152    static CharT null = 0;
153    return &null;
154}
155
156//____________________________________________________________________________//
157
158template<typename CharT>
159inline
160basic_cstring<CharT>::basic_cstring()
161: m_begin( null_str() )
162, m_end( m_begin )
163{
164}
165
166//____________________________________________________________________________//
167
168template<typename CharT>
169inline
170basic_cstring<CharT>::basic_cstring( std_string const& s )
171: m_begin( s.c_str() )
172, m_end( m_begin + s.size() )
173{
174}
175
176//____________________________________________________________________________//
177
178template<typename CharT>
179inline
180basic_cstring<CharT>::basic_cstring( pointer s )
181: m_begin( s ? s : null_str() )
182, m_end  ( m_begin + (s ? traits_type::length( s ) : 0 ) )
183{
184}
185
186//____________________________________________________________________________//
187
188template<typename CharT>
189inline
190basic_cstring<CharT>::basic_cstring( pointer s, size_type arg_size )
191: m_begin( s ), m_end( m_begin + arg_size )
192{
193}
194
195//____________________________________________________________________________//
196
197template<typename CharT>
198inline
199basic_cstring<CharT>::basic_cstring( pointer first, pointer last )
200: m_begin( first )
201, m_end( last )
202{
203}
204
205//____________________________________________________________________________//
206
207template<typename CharT>
208inline typename basic_cstring<CharT>::value_type
209basic_cstring<CharT>::operator[]( size_type index ) const
210{
211    return m_begin[index];
212}
213
214//____________________________________________________________________________//
215
216template<typename CharT>
217inline typename basic_cstring<CharT>::value_type
218basic_cstring<CharT>::at( size_type index ) const
219{
220    if( m_begin + index >= m_end )
221        return (value_type)0;
222
223    return m_begin[index];
224}
225
226//____________________________________________________________________________//
227
228template<typename CharT>
229inline typename basic_cstring<CharT>::size_type
230basic_cstring<CharT>::size() const
231{
232    return m_end - m_begin;
233}
234
235//____________________________________________________________________________//
236
237template<typename CharT>
238inline bool
239basic_cstring<CharT>::is_empty() const
240{
241    return m_end == m_begin;
242}
243
244//____________________________________________________________________________//
245
246template<typename CharT>
247inline bool
248basic_cstring<CharT>::empty() const
249{
250    return is_empty();
251}
252
253//____________________________________________________________________________//
254
255template<typename CharT>
256inline void
257basic_cstring<CharT>::clear()
258{
259    m_begin = m_end;
260}
261
262//____________________________________________________________________________//
263
264template<typename CharT>
265inline void
266basic_cstring<CharT>::resize( size_type new_len )
267{
268    if( m_begin + new_len < m_end )
269        m_end = m_begin + new_len;
270}
271
272//____________________________________________________________________________//
273
274template<typename CharT>
275inline basic_cstring<CharT>&
276basic_cstring<CharT>::trim_left( size_type trim_size )
277{
278    m_begin += trim_size;
279    if( m_end <= m_begin )
280        clear();
281
282    return *this;
283}
284
285//____________________________________________________________________________//
286
287template<typename CharT>
288inline basic_cstring<CharT>&
289basic_cstring<CharT>::trim_left( iterator it )
290{
291    m_begin = it;
292    if( m_end <= m_begin )
293        clear();
294
295    return *this;
296}
297
298//____________________________________________________________________________//
299
300template<typename CharT>
301inline basic_cstring<CharT>&
302basic_cstring<CharT>::trim_left( basic_cstring exclusions )
303{
304    if( exclusions.is_empty() )
305        exclusions = default_trim_ex();
306
307    iterator it;
308    for( it = begin(); it != end(); ++it ) {
309        if( traits_type::find( exclusions.begin(), exclusions.size(), *it ) == (pointer)0 )
310            break;
311    }
312   
313    return trim_left( it );
314}
315
316//____________________________________________________________________________//
317
318template<typename CharT>
319inline basic_cstring<CharT>&
320basic_cstring<CharT>::trim_right( size_type trim_size )
321{
322    m_end  -= trim_size;
323    if( m_end <= m_begin )
324        clear();
325
326    return *this;
327}
328
329//____________________________________________________________________________//
330
331template<typename CharT>
332inline basic_cstring<CharT>&
333basic_cstring<CharT>::trim_right( iterator it )
334{
335    m_end = it;
336    if( m_end <= m_begin )
337        clear();
338
339    return *this;
340}
341
342//____________________________________________________________________________//
343
344template<typename CharT>
345inline basic_cstring<CharT>&
346basic_cstring<CharT>::trim_right( basic_cstring exclusions )
347{
348    if( exclusions.is_empty() )
349        exclusions = default_trim_ex();
350
351    iterator it;
352
353    for( it = end()-1; it != begin()-1; --it ) {
354        if( self_type::traits_type::find( exclusions.begin(),  exclusions.size(), *it ) == (pointer)0 )
355            break;
356    }
357   
358    return trim_right( it+1 );
359}
360
361//____________________________________________________________________________//
362
363template<typename CharT>
364inline basic_cstring<CharT>&
365basic_cstring<CharT>::trim( basic_cstring exclusions )
366{
367    trim_left( exclusions );
368    trim_right( exclusions );
369
370    return *this;
371}
372
373//____________________________________________________________________________//
374
375template<typename CharT>
376inline basic_cstring<CharT>&
377basic_cstring<CharT>::operator=( basic_cstring<CharT> const& s )
378{
379    m_begin = s.m_begin;
380    m_end   = s.m_end;
381
382    return *this;
383}
384
385//____________________________________________________________________________//
386
387template<typename CharT>
388inline basic_cstring<CharT>&
389basic_cstring<CharT>::operator=( std_string const& s )
390{
391    return *this = self_type( s );
392}
393
394//____________________________________________________________________________//
395
396template<typename CharT>
397inline basic_cstring<CharT>&
398basic_cstring<CharT>::operator=( pointer s )
399{
400    return *this = self_type( s );
401}
402
403//____________________________________________________________________________//
404
405template<typename CharT>
406inline basic_cstring<CharT>&
407basic_cstring<CharT>::assign( basic_cstring<CharT> const& s, size_type pos, size_type len )
408{
409    return *this = self_type( s.m_begin + pos, len );
410}
411
412//____________________________________________________________________________//
413
414template<typename CharT>
415inline basic_cstring<CharT>&
416basic_cstring<CharT>::assign( std_string const& s )
417{
418    return *this = self_type( s );
419}
420
421//____________________________________________________________________________//
422
423template<typename CharT>
424inline basic_cstring<CharT>&
425basic_cstring<CharT>::assign( std_string const& s, size_type pos, size_type len )
426{
427    return *this = self_type( s.c_str() + pos, len );
428}
429
430//____________________________________________________________________________//
431
432template<typename CharT>
433inline basic_cstring<CharT>&
434basic_cstring<CharT>::assign( pointer s )
435{
436    return *this = self_type( s );
437}
438
439//____________________________________________________________________________//
440
441template<typename CharT>
442inline basic_cstring<CharT>&
443basic_cstring<CharT>::assign( pointer s, size_type len )
444{
445    return *this = self_type( s, len );
446}
447
448//____________________________________________________________________________//
449
450template<typename CharT>
451inline basic_cstring<CharT>&
452basic_cstring<CharT>::assign( pointer f, pointer l )
453{
454    return *this = self_type( f, l );
455}
456
457//____________________________________________________________________________//
458
459template<typename CharT>
460inline void
461basic_cstring<CharT>::swap( basic_cstring<CharT>& s )
462{
463    // do not want to include alogrithm
464    pointer tmp1    = m_begin;
465    pointer tmp2    = m_end;
466
467    m_begin         = s.m_begin;
468    m_end           = s.m_end;
469
470    s.m_begin       = tmp1;
471    s.m_end         = tmp2;
472}
473
474//____________________________________________________________________________//
475
476template<typename CharT>
477inline typename basic_cstring<CharT>::iterator
478basic_cstring<CharT>::begin()
479{
480    return m_begin;
481}
482
483//____________________________________________________________________________//
484
485template<typename CharT>
486inline typename basic_cstring<CharT>::const_iterator
487basic_cstring<CharT>::begin() const
488{
489    return m_begin;
490}
491
492//____________________________________________________________________________//
493
494template<typename CharT>
495inline typename basic_cstring<CharT>::iterator
496basic_cstring<CharT>::end()
497{
498    return m_end;
499}
500
501//____________________________________________________________________________//
502
503template<typename CharT>
504inline typename basic_cstring<CharT>::const_iterator
505basic_cstring<CharT>::end() const
506{
507    return m_end;
508}
509
510//____________________________________________________________________________//
511
512template<typename CharT>
513inline typename basic_cstring<CharT>::size_type
514basic_cstring<CharT>::find( basic_cstring<CharT> substr ) const
515{
516    if( substr.is_empty() || substr.size() > size() )
517        return (size_type)npos;
518
519    const_iterator it   = begin();
520    const_iterator last = end() - substr.size() + 1;
521
522    while( it != last ) {
523        if( traits_type::compare( it, substr.begin(), substr.size() ) == 0 )
524            break;
525
526        ++it;
527    }
528
529    return it == last ? (size_type)npos : it - begin();
530}
531
532//____________________________________________________________________________//
533
534template<typename CharT>
535inline typename basic_cstring<CharT>::size_type
536basic_cstring<CharT>::rfind( basic_cstring<CharT> substr ) const
537{
538    if( substr.is_empty() || substr.size() > size() )
539        return (size_type)npos;
540
541    const_iterator it   = end() - substr.size();
542    const_iterator last = begin()-1;
543
544    while( it != last ) {
545        if( traits_type::compare( it, substr.begin(), substr.size() ) == 0 )
546            break;
547
548        --it;
549    }
550
551    return it == last ? npos : it - begin();
552}
553
554//____________________________________________________________________________//
555
556template<typename CharT>
557inline basic_cstring<CharT>
558basic_cstring<CharT>::substr( size_type beg_index, size_type end_index ) const
559{
560    return beg_index > size()
561            ?       self_type()
562            : end_index > size()
563                ?   self_type( m_begin + beg_index, m_end )
564                :   self_type( m_begin + beg_index, m_begin + end_index );
565}
566
567//____________________________________________________________________________//
568
569template<typename CharT>
570inline basic_cstring<CharT>
571basic_cstring<CharT>::default_trim_ex()
572{
573    static CharT ws[3] = { CharT(' '), CharT('\t'), CharT('\n') }; //!! wide case
574
575    return self_type( ws, 3 );
576}
577
578//____________________________________________________________________________//
579
580// ************************************************************************** //
581// **************             comparison operators             ************** //
582// ************************************************************************** //
583
584template<typename CharT1,typename CharT2>
585inline bool
586operator==( basic_cstring<CharT1> const& s1, basic_cstring<CharT2> const& s2 )
587{
588    typedef typename basic_cstring<CharT1>::traits_type traits_type;
589    return s1.size() == s2.size() &&
590               traits_type::compare( s1.begin(), s2.begin(), s1.size() ) == 0;
591}
592
593//____________________________________________________________________________//
594
595template<typename CharT1,typename CharT2>
596inline bool
597operator==( basic_cstring<CharT1> const& s1, CharT2* s2 )
598{
599#if !defined(__DMC__)
600    return s1 == basic_cstring<CharT2>( s2 );
601#else
602    return s1 == basic_cstring<CharT2 const>( s2 );
603#endif
604}
605
606//____________________________________________________________________________//
607
608template<typename CharT>
609inline bool
610operator==( basic_cstring<CharT> const& s1, typename basic_cstring<CharT>::std_string const& s2 )
611{
612    return s1 == basic_cstring<CharT>( s2 );
613}
614
615//____________________________________________________________________________//
616
617template<typename CharT1,typename CharT2>
618inline bool
619operator==( CharT1* s2, basic_cstring<CharT2> const& s1 )
620{
621    return s1 == s2;
622}
623
624//____________________________________________________________________________//
625
626template<typename CharT>
627inline bool
628operator==( typename basic_cstring<CharT>::std_string const& s2, basic_cstring<CharT> const& s1 )
629{
630    return s1 == s2;
631}
632
633//____________________________________________________________________________//
634
635template<typename CharT>
636inline bool
637operator!=( basic_cstring<CharT> const& s1, CharT* s2 )
638{
639    return !(s1 == s2);
640}
641
642//____________________________________________________________________________//
643
644template<typename CharT>
645inline bool
646operator!=( CharT* s2, basic_cstring<CharT> const& s1 )
647{
648    return !(s1 == s2);
649}
650
651//____________________________________________________________________________//
652
653template<typename CharT>
654inline bool
655operator!=( basic_cstring<CharT> const& s1, basic_cstring<CharT> const& s2 )
656{
657    return !(s1 == s2);
658}
659
660//____________________________________________________________________________//
661
662template<typename CharT>
663inline bool
664operator!=( basic_cstring<CharT> const& s1, typename basic_cstring<CharT>::std_string const& s2 )
665{
666    return !(s1 == s2);
667}
668
669//____________________________________________________________________________//
670
671template<typename CharT>
672inline bool
673operator!=( typename basic_cstring<CharT>::std_string const& s2, basic_cstring<CharT> const& s1 )
674{
675    return !(s1 == s2);
676}
677
678//____________________________________________________________________________//
679
680// ************************************************************************** //
681// **************                  first_char                  ************** //
682// ************************************************************************** //
683
684template<typename CharT>
685inline typename basic_cstring<CharT>::value_type
686first_char( basic_cstring<CharT> source )
687{
688    typedef typename basic_cstring<CharT>::value_type string_value_type;
689
690    return source.is_empty() ? (string_value_type)0 : *source.begin();
691}
692
693//____________________________________________________________________________//
694
695// ************************************************************************** //
696// **************                  last_char                   ************** //
697// ************************************************************************** //
698
699template<typename CharT>
700inline typename basic_cstring<CharT>::value_type
701last_char( basic_cstring<CharT> source )
702{
703    typedef typename basic_cstring<CharT>::value_type string_value_type;
704
705    return source.is_empty() ? (string_value_type)0 : *(source.end()-1);
706}
707
708//____________________________________________________________________________//
709
710// ************************************************************************** //
711// **************                  assign_op                   ************** //
712// ************************************************************************** //
713
714template<typename CharT1, typename CharT2>
715inline void
716#if BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x530) )
717assign_op( std::basic_string<CharT1>& target, basic_cstring<CharT2> const& src, int )
718#else
719assign_op( std::basic_string<CharT1>& target, basic_cstring<CharT2> src, int )
720#endif
721{
722    target.assign( src.begin(), src.size() );
723}
724
725//____________________________________________________________________________//
726
727} // namespace unit_test
728
729} // namespace boost
730
731//____________________________________________________________________________//
732
733#include <boost/test/detail/enable_warnings.hpp>
734
735// ***************************************************************************
736//  Revision History :
737// 
738//  $Log: basic_cstring.hpp,v $
739//  Revision 1.9  2005/07/13 21:49:46  danieljames
740//  Boost.Test workarounds for Digital Mars bugs.
741//
742//  Revision 1.8  2005/04/12 06:49:05  rogeeff
743//  assign_to -> assign_op
744//
745//  Revision 1.7  2005/03/23 21:02:37  rogeeff
746//  Sunpro CC 5.3 fixes
747//
748//  Revision 1.6  2005/03/22 07:02:57  rogeeff
749//  assign_to made free function
750//
751//  Revision 1.5  2005/03/22 07:00:56  rogeeff
752//  assign_to made free function
753//
754//  Revision 1.4  2005/02/20 08:27:08  rogeeff
755//  This a major update for Boost.Test framework. See release docs for complete list of fixes/updates
756//
757//  Revision 1.3  2005/02/01 06:40:08  rogeeff
758//  copyright update
759//  old log entries removed
760//  minor stilistic changes
761//  depricated tools removed
762//
763//  Revision 1.2  2005/01/22 19:22:13  rogeeff
764//  implementation moved into headers section to eliminate dependency of included/minimal component on src directory
765//
766//  Revision 1.1  2005/01/22 18:21:40  rogeeff
767//  moved sharable staff into utils
768//
769//  Revision 1.12  2005/01/21 07:33:51  rogeeff
770//  small aCC fix
771//
772// ***************************************************************************
773
774#endif // BOOST_TEST_BASIC_CSTRING_HPP_071894GER
Note: See TracBrowser for help on using the repository browser.