You've already forked mariadb-columnstore-engine
							
							
				mirror of
				https://github.com/mariadb-corporation/mariadb-columnstore-engine.git
				synced 2025-11-03 17:13:17 +03:00 
			
		
		
		
	
		
			
				
	
	
		
			168 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			168 lines
		
	
	
		
			5.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
 | 
						|
// (C) Copyright 2003-2007 Jonathan Turkanis
 | 
						|
// Distributed under the Boost Software License, Version 1.0. (See accompanying
 | 
						|
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
 | 
						|
 | 
						|
// See http://www.boost.org/libs/iostreams for documentation.
 | 
						|
 | 
						|
#ifndef BOOST_IOSTREAMS_INVERT_HPP_INCLUDED
 | 
						|
#define BOOST_IOSTREAMS_INVERT_HPP_INCLUDED
 | 
						|
 | 
						|
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
 | 
						|
# pragma once
 | 
						|
#endif              
 | 
						|
 | 
						|
#include <algorithm>                             // copy, min.  
 | 
						|
#include <boost/assert.hpp>
 | 
						|
#include <boost/config.hpp>                      // BOOST_DEDUCED_TYPENAME.       
 | 
						|
#include <boost/detail/workaround.hpp>           // default_filter_buffer_size.
 | 
						|
#include <boost/iostreams/char_traits.hpp>
 | 
						|
#include <boost/iostreams/compose.hpp>
 | 
						|
#include <boost/iostreams/constants.hpp>
 | 
						|
#include <boost/iostreams/device/array.hpp>
 | 
						|
#include <boost/iostreams/detail/buffer.hpp>
 | 
						|
#include <boost/iostreams/detail/counted_array.hpp>
 | 
						|
#include <boost/iostreams/detail/execute.hpp>
 | 
						|
#include <boost/iostreams/detail/functional.hpp> // clear_flags, call_reset
 | 
						|
#include <boost/mpl/if.hpp>
 | 
						|
#include <boost/ref.hpp>
 | 
						|
#include <boost/shared_ptr.hpp>
 | 
						|
#include <boost/type_traits/is_convertible.hpp>
 | 
						|
 | 
						|
// Must come last.
 | 
						|
#include <boost/iostreams/detail/config/disable_warnings.hpp>  // MSVC.
 | 
						|
 | 
						|
namespace boost { namespace iostreams {
 | 
						|
 | 
						|
//
 | 
						|
// Template name: inverse.
 | 
						|
// Template parameters:
 | 
						|
//      Filter - A model of InputFilter or OutputFilter.
 | 
						|
// Description: Generates an InputFilter from an OutputFilter or
 | 
						|
//      vice versa.
 | 
						|
//
 | 
						|
template<typename Filter>
 | 
						|
class inverse {
 | 
						|
private:
 | 
						|
    BOOST_STATIC_ASSERT(is_filter<Filter>::value);
 | 
						|
    typedef typename category_of<Filter>::type   base_category;
 | 
						|
    typedef reference_wrapper<Filter>            filter_ref;
 | 
						|
public:
 | 
						|
    typedef typename char_type_of<Filter>::type  char_type;
 | 
						|
    typedef typename int_type_of<Filter>::type   int_type;
 | 
						|
    typedef char_traits<char_type>               traits_type;
 | 
						|
    typedef typename 
 | 
						|
            mpl::if_<
 | 
						|
                is_convertible<
 | 
						|
                    base_category,
 | 
						|
                    input
 | 
						|
                >,
 | 
						|
                output,
 | 
						|
                input
 | 
						|
            >::type                              mode;
 | 
						|
    struct category 
 | 
						|
        : mode, 
 | 
						|
          filter_tag, 
 | 
						|
          multichar_tag, 
 | 
						|
          closable_tag 
 | 
						|
        { };
 | 
						|
    explicit inverse( const Filter& filter, 
 | 
						|
                      std::streamsize buffer_size = 
 | 
						|
                          default_filter_buffer_size) 
 | 
						|
        : pimpl_(new impl(filter, buffer_size))
 | 
						|
        { }
 | 
						|
 | 
						|
    template<typename Source>
 | 
						|
    std::streamsize read(Source& src, char* s, std::streamsize n)
 | 
						|
    {
 | 
						|
        typedef detail::counted_array_sink<char_type>  array_sink;
 | 
						|
        typedef composite<filter_ref, array_sink>      filtered_array_sink;
 | 
						|
 | 
						|
        BOOST_ASSERT((flags() & f_write) == 0);
 | 
						|
        if (flags() == 0) {
 | 
						|
            flags() = f_read;
 | 
						|
            buf().set(0, 0);
 | 
						|
        }
 | 
						|
 | 
						|
        filtered_array_sink snk(filter(), array_sink(s, n));
 | 
						|
        int_type status;
 | 
						|
        for ( status = traits_type::good();
 | 
						|
              snk.second().count() < n && status == traits_type::good(); )
 | 
						|
        {
 | 
						|
            status = buf().fill(src);
 | 
						|
            buf().flush(snk);
 | 
						|
        }
 | 
						|
        return snk.second().count() == 0 &&
 | 
						|
               status == traits_type::eof() 
 | 
						|
                   ? 
 | 
						|
               -1
 | 
						|
                   : 
 | 
						|
               snk.second().count();
 | 
						|
    }
 | 
						|
 | 
						|
    template<typename Sink>
 | 
						|
    std::streamsize write(Sink& dest, const char* s, std::streamsize n)
 | 
						|
    {
 | 
						|
        typedef detail::counted_array_source<char_type>  array_source;
 | 
						|
        typedef composite<filter_ref, array_source>      filtered_array_source;
 | 
						|
 | 
						|
        BOOST_ASSERT((flags() & f_read) == 0);
 | 
						|
        if (flags() == 0) {
 | 
						|
            flags() = f_write;
 | 
						|
            buf().set(0, 0);
 | 
						|
        }
 | 
						|
        
 | 
						|
        filtered_array_source src(filter(), array_source(s, n));
 | 
						|
        for (bool good = true; src.second().count() < n && good; ) {
 | 
						|
            buf().fill(src);
 | 
						|
            good = buf().flush(dest);
 | 
						|
        }
 | 
						|
        return src.second().count();
 | 
						|
    }
 | 
						|
 | 
						|
    template<typename Device>
 | 
						|
    void close(Device& dev)
 | 
						|
    {
 | 
						|
        detail::execute_all(
 | 
						|
            detail::flush_buffer(buf(), dev, (flags() & f_write) != 0),
 | 
						|
            detail::call_close_all(pimpl_->filter_, dev),
 | 
						|
            detail::clear_flags(flags())
 | 
						|
        );
 | 
						|
    }
 | 
						|
private:
 | 
						|
    filter_ref filter() { return boost::ref(pimpl_->filter_); }
 | 
						|
    detail::buffer<char_type>& buf() { return pimpl_->buf_; }
 | 
						|
    int& flags() { return pimpl_->flags_; }
 | 
						|
    
 | 
						|
    enum flags_ {
 | 
						|
        f_read = 1, f_write = 2
 | 
						|
    };
 | 
						|
 | 
						|
    struct impl {
 | 
						|
        impl(const Filter& filter, std::streamsize n) 
 | 
						|
            : filter_(filter), buf_(n), flags_(0)
 | 
						|
        { buf_.set(0, 0); }
 | 
						|
        Filter                     filter_;
 | 
						|
        detail::buffer<char_type>  buf_;
 | 
						|
        int                        flags_;
 | 
						|
    };
 | 
						|
    shared_ptr<impl> pimpl_;
 | 
						|
};
 | 
						|
 | 
						|
//
 | 
						|
// Template name: invert.
 | 
						|
// Template parameters:
 | 
						|
//      Filter - A model of InputFilter or OutputFilter.
 | 
						|
// Description: Returns an instance of an appropriate specialization of inverse.
 | 
						|
//
 | 
						|
template<typename Filter>
 | 
						|
inverse<Filter> invert(const Filter& f) { return inverse<Filter>(f); }
 | 
						|
                    
 | 
						|
//----------------------------------------------------------------------------//
 | 
						|
 | 
						|
} } // End namespaces iostreams, boost.
 | 
						|
 | 
						|
#include <boost/iostreams/detail/config/enable_warnings.hpp>  // MSVC.
 | 
						|
 | 
						|
#endif // #ifndef BOOST_IOSTREAMS_INVERT_HPP_INCLUDED
 |