/Src/Dependencies/Boost/boost/iostreams/filter/test.hpp
http://hadesmem.googlecode.com/ · C++ Header · 322 lines · 276 code · 27 blank · 19 comment · 25 complexity · c35ce884ec414eff123300e4e68fb624 MD5 · raw file
- // (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
- // (C) Copyright 2005-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_FILTER_TEST_HPP_INCLUDED
- #if defined(_MSC_VER) && (_MSC_VER >= 1020)
- # pragma once
- #endif
- #include <boost/config.hpp> // BOOST_MSVC,put size_t in std.
- #include <boost/detail/workaround.hpp>
- #include <algorithm> // min.
- #include <cstddef> // size_t.
- #if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) || \
- BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) || \
- BOOST_WORKAROUND(__MWERKS__, <= 0x3003) \
- /**/
- # include <cstdlib> // rand.
- #endif
- #include <cstring> // memcpy, strlen.
- #include <iterator>
- #include <string>
- #include <vector>
- #if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) && \
- !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) && \
- !BOOST_WORKAROUND(__MWERKS__, <= 0x3003) \
- /**/
- # include <boost/random/linear_congruential.hpp>
- # include <boost/random/uniform_smallint.hpp>
- #endif
- #include <boost/iostreams/categories.hpp>
- #include <boost/iostreams/compose.hpp>
- #include <boost/iostreams/copy.hpp>
- #include <boost/iostreams/detail/bool_trait_def.hpp>
- #include <boost/iostreams/detail/ios.hpp>
- #include <boost/iostreams/device/array.hpp>
- #include <boost/iostreams/device/back_inserter.hpp>
- #include <boost/iostreams/operations.hpp>
- #include <boost/mpl/bool.hpp>
- #include <boost/type_traits/is_array.hpp>
- #include <boost/type_traits/is_same.hpp>
- #undef memcpy
- #undef rand
- #undef strlen
- #if defined(BOOST_NO_STDC_NAMESPACE) && !defined(__LIBCOMO__)
- namespace std {
- using ::memcpy;
- using ::strlen;
- #if BOOST_WORKAROUND(BOOST_MSVC, <= 1300) || \
- BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) || \
- BOOST_WORKAROUND(__MWERKS__, <= 0x3003) \
- /**/
- using ::rand;
- #endif
- }
- #endif
- namespace boost { namespace iostreams {
- BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_string, std::basic_string, 3)
- const std::streamsize default_increment = 5;
- #if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) && \
- !BOOST_WORKAROUND(__BORLANDC__, BOOST_TESTED_AT(0x564)) && \
- !BOOST_WORKAROUND(__MWERKS__, <= 0x3003) \
- /**/
- std::streamsize rand(int inc)
- {
- static rand48 random_gen;
- static uniform_smallint<int> random_dist(0, inc);
- return random_dist(random_gen);
- }
- #else
- std::streamsize rand(int inc)
- {
- return (std::rand() * inc + 1) / RAND_MAX;
- }
- #endif
- class non_blocking_source {
- public:
- typedef char char_type;
- struct category
- : source_tag,
- peekable_tag
- { };
- explicit non_blocking_source( const std::string& data,
- std::streamsize inc = default_increment )
- : data_(data), inc_(inc), pos_(0)
- { }
- std::streamsize read(char* s, std::streamsize n)
- {
- if (pos_ == static_cast<std::streamsize>(data_.size()))
- return -1;
- std::streamsize avail =
- (std::min) (n, static_cast<std::streamsize>(data_.size() - pos_));
- std::streamsize amt = (std::min) (rand(inc_), avail);
- if (amt)
- std::memcpy(s, data_.c_str() + pos_, amt);
- pos_ += amt;
- return amt;
- }
- bool putback(char c)
- {
- if (pos_ > 0) {
- data_[--pos_] = c;
- return true;
- }
- return false;
- }
- private:
- std::string data_;
- std::streamsize inc_, pos_;
- };
- class non_blocking_sink : public sink {
- public:
- non_blocking_sink( std::string& dest,
- std::streamsize inc = default_increment )
- : dest_(dest), inc_(inc)
- { }
- std::streamsize write(const char* s, std::streamsize n)
- {
- std::streamsize amt = (std::min) (rand(inc_), n);
- dest_.insert(dest_.end(), s, s + amt);
- return amt;
- }
- private:
- non_blocking_sink& operator=(const non_blocking_sink&);
- std::string& dest_;
- std::streamsize inc_;
- };
-
- //--------------Definition of test_input_filter-------------------------------//
- template<typename Filter>
- bool test_input_filter( Filter filter,
- const std::string& input,
- const std::string& output,
- mpl::true_ )
- {
- for ( int inc = default_increment;
- inc < default_increment * 40;
- inc += default_increment )
- {
- non_blocking_source src(input, inc);
- std::string dest;
- iostreams::copy(compose(filter, src), iostreams::back_inserter(dest));
- if (dest != output)
- return false;
- }
- return true;
- }
- template<typename Filter, typename Source1, typename Source2>
- bool test_input_filter( Filter filter,
- const Source1& input,
- const Source2& output,
- mpl::false_ )
- {
- std::string in;
- std::string out;
- iostreams::copy(input, iostreams::back_inserter(in));
- iostreams::copy(output, iostreams::back_inserter(out));
- return test_input_filter(filter, in, out);
- }
- template<typename Filter, typename Source1, typename Source2>
- bool test_input_filter( Filter filter,
- const Source1& input,
- const Source2& output )
- {
- // Use tag dispatch to compensate for bad overload resolution.
- return test_input_filter( filter, input, output,
- is_string<Source1>() );
- }
- //--------------Definition of test_output_filter------------------------------//
- template<typename Filter>
- bool test_output_filter( Filter filter,
- const std::string& input,
- const std::string& output,
- mpl::true_ )
- {
- for ( int inc = default_increment;
- inc < default_increment * 40;
- inc += default_increment )
- {
- array_source src(input.data(), input.data() + input.size());
- std::string dest;
- iostreams::copy(src, compose(filter, non_blocking_sink(dest, inc)));
- if (dest != output )
- return false;
- }
- return true;
- }
- template<typename Filter, typename Source1, typename Source2>
- bool test_output_filter( Filter filter,
- const Source1& input,
- const Source2& output,
- mpl::false_ )
- {
- std::string in;
- std::string out;
- iostreams::copy(input, iostreams::back_inserter(in));
- iostreams::copy(output, iostreams::back_inserter(out));
- return test_output_filter(filter, in, out);
- }
- template<typename Filter, typename Source1, typename Source2>
- bool test_output_filter( Filter filter,
- const Source1& input,
- const Source2& output )
- {
- // Use tag dispatch to compensate for bad overload resolution.
- return test_output_filter( filter, input, output,
- is_string<Source1>() );
- }
- //--------------Definition of test_filter_pair--------------------------------//
- template<typename OutputFilter, typename InputFilter>
- bool test_filter_pair( OutputFilter out,
- InputFilter in,
- const std::string& data,
- mpl::true_ )
- {
- for ( int inc = default_increment;
- inc <= default_increment * 40;
- inc += default_increment )
- {
- {
- array_source src(data.data(), data.data() + data.size());
- std::string temp;
- std::string dest;
- iostreams::copy(src, compose(out, non_blocking_sink(temp, inc)));
- iostreams::copy(
- compose(in, non_blocking_source(temp, inc)),
- iostreams::back_inserter(dest)
- );
- if (dest != data)
- return false;
- }
- {
- array_source src(data.data(), data.data() + data.size());
- std::string temp;
- std::string dest;
- iostreams::copy(src, compose(out, non_blocking_sink(temp, inc)));
- // truncate the file, this should not loop, it may throw
- // std::ios_base::failure, which we swallow.
- try {
- temp.resize(temp.size() / 2);
- iostreams::copy(
- compose(in, non_blocking_source(temp, inc)),
- iostreams::back_inserter(dest)
- );
- } catch(std::ios_base::failure&) {}
- }
- {
- array_source src(data.data(), data.data() + data.size());
- std::string temp;
- std::string dest;
- iostreams::copy(compose(out, src), non_blocking_sink(temp, inc));
- iostreams::copy(
- non_blocking_source(temp, inc),
- compose(in, iostreams::back_inserter(dest))
- );
- if (dest != data)
- return false;
- }
- {
- array_source src(data.data(), data.data() + data.size());
- std::string temp;
- std::string dest;
- iostreams::copy(compose(out, src), non_blocking_sink(temp, inc));
- // truncate the file, this should not loop, it may throw
- // std::ios_base::failure, which we swallow.
- try {
- temp.resize(temp.size() / 2);
- iostreams::copy(
- non_blocking_source(temp, inc),
- compose(in, iostreams::back_inserter(dest))
- );
- } catch(std::ios_base::failure&) {}
- }
- }
- return true;
- }
- template<typename OutputFilter, typename InputFilter, typename Source>
- bool test_filter_pair( OutputFilter out,
- InputFilter in,
- const Source& data,
- mpl::false_ )
- {
- std::string str;
- iostreams::copy(data, iostreams::back_inserter(str));
- return test_filter_pair(out, in, str);
- }
- template<typename OutputFilter, typename InputFilter, typename Source>
- bool test_filter_pair( OutputFilter out,
- InputFilter in,
- const Source& data )
- {
- // Use tag dispatch to compensate for bad overload resolution.
- return test_filter_pair(out, in, data, is_string<Source>());
- }
- } } // End namespaces iostreams, boost.
- #endif // #ifndef BOOST_IOSTREAMS_FILTER_TEST_HPP_INCLUDED