CppCMS
booster/locale/collator.h
00001 //
00002 //  Copyright (c) 2009-2011 Artyom Beilis (Tonkikh)
00003 //
00004 //  Distributed under the Boost Software License, Version 1.0. (See
00005 //  accompanying file LICENSE_1_0.txt or copy at
00006 //  http://www.boost.org/LICENSE_1_0.txt)
00007 //
00008 #ifndef BOOSTER_LOCALE_COLLATOR_H_INCLUDED
00009 #define BOOSTER_LOCALE_COLLATOR_H_INCLUDED
00010 
00011 #include <booster/config.h>
00012 #ifdef BOOSTER_MSVC
00013 #  pragma warning(push)
00014 #  pragma warning(disable : 4275 4251 4231 4660)
00015 #endif
00016 #include <locale>
00017 
00018 
00019 namespace booster {
00020 namespace locale {
00021 
00022     class info;
00023 
00030 
00034 
00035     class collator_base {
00036     public:
00040         typedef enum {
00041             primary     = 0, 
00042             secondary   = 1, 
00043             tertiary    = 2, 
00044             quaternary  = 3, 
00045             identical   = 4  
00046         } level_type;
00047     };
00048     
00055     template<typename CharType>
00056     class collator : 
00057         public std::collate<CharType>,
00058         public collator_base
00059     {
00060     public:
00064         typedef CharType char_type;
00068         typedef std::basic_string<CharType> string_type;
00069         
00070 
00077         int compare(level_type level,
00078                     char_type const *b1,char_type const *e1,
00079                     char_type const *b2,char_type const *e2) const
00080         {
00081             return do_compare(level,b1,e1,b2,e2);
00082         }
00094         string_type transform(level_type level,char_type const *b,char_type const *e) const
00095         {
00096             return do_transform(level,b,e);
00097         }
00098 
00106         long hash(level_type level,char_type const *b,char_type const *e) const
00107         {
00108             return do_hash(level,b,e);
00109         }
00110 
00118         int compare(level_type level,string_type const &l,string_type const &r) const
00119         {
00120             return do_compare(level,l.data(),l.data()+l.size(),r.data(),r.data()+r.size());
00121         }
00122 
00128 
00129         long hash(level_type level,string_type const &s) const
00130         {
00131             return do_hash(level,s.data(),s.data()+s.size());
00132         }
00142         string_type transform(level_type level,string_type const &s) const
00143         {
00144             return do_transform(level,s.data(),s.data()+s.size());
00145         }
00146         
00147     protected:
00148 
00152         collator(size_t refs = 0) : std::collate<CharType>(refs) 
00153         {
00154         }
00155 
00156         virtual ~collator()
00157         {
00158         }
00159         
00164         virtual int do_compare( char_type const *b1,char_type const *e1,
00165                                 char_type const *b2,char_type const *e2) const
00166         {
00167             return do_compare(identical,b1,e1,b2,e2);
00168         }
00173         virtual string_type do_transform(char_type const *b,char_type const *e) const
00174         {
00175             return do_transform(identical,b,e);
00176         }
00181         virtual long do_hash(char_type const *b,char_type const *e) const
00182         {
00183             return do_hash(identical,b,e);
00184         }
00185 
00189         virtual int do_compare( level_type level,
00190                                 char_type const *b1,char_type const *e1,
00191                                 char_type const *b2,char_type const *e2) const = 0;
00195         virtual string_type do_transform(level_type level,char_type const *b,char_type const *e) const = 0;
00199         virtual long do_hash(level_type level,char_type const *b,char_type const *e) const = 0;
00200 
00201 
00202     };
00203 
00216     template<typename CharType,collator_base::level_type default_level = collator_base::identical>
00217     struct comparator
00218     {
00219     public:
00225         comparator(std::locale const &l=std::locale(),collator_base::level_type level=default_level) : 
00226             locale_(l),
00227             level_(level)
00228         {
00229         }
00230 
00234         bool operator()(std::basic_string<CharType> const &left,std::basic_string<CharType> const &right) const
00235         {
00236             return std::use_facet<collator<CharType> >(locale_).compare(level_,left,right) < 0;
00237         }
00238     private:
00239         std::locale locale_;
00240         collator_base::level_type level_;
00241     };
00242 
00243 
00247 
00248     } // locale
00249 } // boost
00250 
00251 #ifdef BOOSTER_MSVC
00252 #pragma warning(pop)
00253 #endif
00254 
00255 
00256 #endif
00257 
00258 
00259 
00260 
00261 // vim: tabstop=4 expandtab shiftwidth=4 softtabstop=4