输出具有begin和end函数的容器

Print containers in a generic way, as long as the functions begin and end applies.
#ifndef MY_container_io_HEADER
#define MY_container_io_HEADER

#include 
   
   
    
    
#include 
    
    
     
     // 保证T[N]的begin和end函数能找到
#include 
     
     
      
      
#include 
      
      
       
       
#include 
       
       
         #include 
        
          namespace std{ template 
         
           class basic_ostream; namespace{ template 
          
            false_type has_begin_end_helper(int, Container&&); template 
           
             auto has_begin_end_helper(double, Container&& container)-> typename enable_if 
            
              ::type; template 
             
               struct has_begin_end: decltype(has_begin_end_helper(0., declval 
              
                ())){}; template 
               
                 struct format_t : boost::intrusive_ref_counter 
                 
                 
                   >{ public: using intrusive_ptr = boost::intrusive_ptr 
                  
                    ; static format_t*& get_format_ptr(ios_base &ios){ return reinterpret_cast 
                   
                     (ios.pword(get_index())); } static format_t& instance(CharType const *open, CharType const *close, CharType const* del){ size_t const len_o = strlen(open), len_c = strlen(close), len_d = strlen(del); if (len_o != len_c || len_c != len_d) throw invalid_argument("size not consistant"); using const_ptr = CharType *const; const_ptr o = new CharType[len_o + 1], c = new CharType[len_o + 1], d = new CharType[len_o + 1]; strcpy(o, open); strcpy(c, close); strcpy(d, del); return *(new format_t 
                    
                      (o, c, d, len_o)); } private: boost::scoped_array 
                     
                       open_str, close_str, delimiter_str; ptrdiff_t level; format_t(CharType const* o, CharType const* c, CharType const* d, size_t const l) : open_str(o), close_str(c), delimiter_str(d), level(l){} static int get_index(){ static const int index = std::ios::xalloc(); return index; } static void call_back(ios_base::event type, ios_base& ios, int index){ switch (type){ case std::ios_base::erase_event: intrusive_ptr_release(get_format_ptr(ios)); break; case std::ios_base::copyfmt_event: intrusive_ptr_add_ref(get_format_ptr(ios)); break; } } static intrusive_ptr& get_intrusive_ptr(ios_base &ios){ return reinterpret_cast 
                      
                        (ios.pword(get_index())); } template 
                       
                         friend basic_ostream 
                        
                          & operator<<(basic_ostream 
                         
                           & ostr, format_t &format){ intrusive_ptr& p = get_intrusive_ptr(ostr); if (!p) ostr.register_callback(&call_back, get_index());// 没有注册过回调函数 intrusive_ptr(std::addressof(format)).swap(p); return ostr; } friend void open(format_t *const format, CharType &o, CharType &c, CharType &d){ if (format && --format->level >= 0){ auto const level = format->level; o = format->open_str[level]; c = format->close_str[level]; d = format->delimiter_str[level]; } else{ o = '('; c = ')'; d = ' '; } } friend void close(format_t *const format){ if (format) ++format->level; } }; } template 
                          
                            format_t 
                           
                             & container(CharType const *open, CharType const *close, CharType const* del){ return format_t 
                            
                              ::instance(open, close, del); } template 
                             
                               typename enable_if 
                               
                               
                                 ::value, basic_ostream 
                                
                                  &>::type operator<<(basic_ostream 
                                 
                                   & ostr, Container const &v){ auto const format = format_t 
                                  
                                    ::get_format_ptr(ostr); CharT o, c, d; open(format, o, c, d); ostr << o; auto p = begin(v); auto const q = end(v); if (p != q){ ostr << *p++; while (p != q){ ostr << d << *p++; } } ostr << c; close(format); return ostr; } template 
                                   
                                     basic_ostream 
                                    
                                      & operator<<(basic_ostream 
                                     
                                       & ostr, std::pair 
                                      
                                        const &v){ auto const format = format_t 
                                       
                                         ::get_format_ptr(ostr); CharT o, c, d; open(format, o, c, d); ostr << o << v.first << d << v.second << c; close(format); return ostr; } } #endif #include 
                                        
                                          #include 
                                         
                                           #include 
                                          
                                            #include 
                                           
                                             #include 
                                            
                                              #include 
                                             
                                               #include 
                                               #include 
                                               
                                                 #include 
                                                
                                                  #include 
                                                 
                                                   #include 
                                                  
                                                    #include 
                                                   
                                                     int main(){ std::vector 
                                                    
                                                      v{1, 2, 3}; std::list 
                                                     
                                                       l{1, 2, 3}; std::array 
                                                      
                                                        a{{1, 2, 3}}; std::set 
                                                       
                                                         s{1, 2, 3}; int r[] = {1, 2, 3}; std::deque 
                                                        
                                                          d{1, 2, 3}; std::forward_list 
                                                         
                                                           f{1, 2, 3}; std::string str("1-2-3"); std::map 
                                                          
                                                            m{{1, 1}, {2, 2}, {3, 3}}; std::cout< 
                                                           
                                                             <<"\n" < 
                                                            
                                                              <", ">", " ")< 
                                                             
                                                               <<"\n" < 
                                                              
                                                                t(1, .1, '1'); std::cout< 
                                                               
                                                                 <<"\n"; return 0; } 
                                                                
                                                               
                                                              
                                                             
                                                            
                                                           
                                                          
                                                         
                                                        
                                                       
                                                      
                                                     
                                                    
                                                   
                                                  
                                                 
                                                
                                              
                                             
                                            
                                           
                                          
                                         
                                        
                                       
                                      
                                     
                                    
                                   
                                  
                                 
                                
                               
                              
                             
                            
                           
                          
                         
                        
                       
                      
                     
                    
                   
                  
                 
                
               
              
             
            
           
          
         
       
      
      
     
     
    
    
   
   

使用的技术在C++中称为SFINAE。

终极目标是做得和boost::tuple一样方便地输入输出,并支持左括弧、右括弧、分隔符。

欢迎转载,请注明出处。

Alternative: http://louisdx.github.io/cxx-prettyprint/ 目前,需要将37~45行进行修改才能在vs2013上编译。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

cqdjyy01234

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值