Optimizations for boost and std array (refs #7065)

[SVN r79230]
This commit is contained in:
Antony Polukhin
2012-07-02 18:30:21 +00:00
parent c6318e3819
commit e3cd0ca7fa
3 changed files with 421 additions and 17 deletions
+160 -17
View File
@@ -138,6 +138,12 @@ namespace boost
#include <cmath>
#include <istream>
#if !defined(BOOST_NO_CXX11_HDR_ARRAY) && defined(BOOST_HAS_TR1_ARRAY)
#include <array>
#endif
#include <boost/array.hpp>
#include <boost/numeric/conversion/cast.hpp>
#include <boost/type_traits/make_unsigned.hpp>
#include <boost/type_traits/is_signed.hpp>
@@ -224,42 +230,56 @@ namespace boost {
typedef char type;
};
template<typename CharT>
template <typename CharT>
struct stream_char<CharT*>
{
typedef BOOST_DEDUCED_TYPENAME stream_char<CharT>::type type;
};
template<typename CharT>
template <typename CharT>
struct stream_char<const CharT*>
{
typedef BOOST_DEDUCED_TYPENAME stream_char<CharT>::type type;
};
template<typename CharT>
template <typename CharT>
struct stream_char<iterator_range<CharT*> >
{
typedef BOOST_DEDUCED_TYPENAME stream_char<CharT*>::type type;
};
template<typename CharT>
template <typename CharT>
struct stream_char<iterator_range<const CharT*> >
{
typedef BOOST_DEDUCED_TYPENAME stream_char<const CharT*>::type type;
};
template<class CharT, class Traits, class Alloc>
template <class CharT, class Traits, class Alloc>
struct stream_char< std::basic_string<CharT, Traits, Alloc> >
{
typedef CharT type;
};
template<class CharT, class Traits, class Alloc>
template <class CharT, class Traits, class Alloc>
struct stream_char< ::boost::container::basic_string<CharT, Traits, Alloc> >
{
typedef CharT type;
};
template<typename CharT, std::size_t N>
struct stream_char<boost::array<CharT, N> >
{
typedef BOOST_DEDUCED_TYPENAME stream_char<CharT>::type type;
};
#if !defined(BOOST_NO_CXX11_HDR_ARRAY) && defined(BOOST_HAS_TR1_ARRAY)
template <typename CharT, std::size_t N>
struct stream_char<std::array<CharT, N> >
{
typedef BOOST_DEDUCED_TYPENAME stream_char<CharT>::type type;
};
#endif // !defined(BOOST_NO_CXX11_HDR_ARRAY) && defined(BOOST_HAS_TR1_ARRAY)
#if !defined(BOOST_LCAST_NO_WCHAR_T) && defined(BOOST_NO_INTRINSIC_WCHAR_T)
template<>
struct stream_char<wchar_t>
@@ -1259,7 +1279,6 @@ namespace boost {
return true;
}
#ifndef BOOST_LCAST_NO_WCHAR_T
template <class T>
bool shl_char_array(T const* str)
{
@@ -1268,7 +1287,13 @@ namespace boost {
"Use boost::locale instead" );
return shl_input_streamable(str);
}
#endif
bool shl_char_array_limited(CharT const* str, std::size_t max_size)
{
start = const_cast<CharT*>(str);
finish = std::find(start, start + max_size, static_cast<CharT>(0));
return true;
}
template<typename InputStreamable>
bool shl_input_streamable(InputStreamable& input)
@@ -1494,8 +1519,58 @@ namespace boost {
return shl_real_type(static_cast<double>(val), start, finish);
#endif
}
template <std::size_t N>
bool operator<<(boost::array<CharT, N> const& input)
{ return shl_char_array_limited(input.begin(), N); }
template<class InStreamable>
template <std::size_t N>
bool operator<<(boost::array<unsigned char, N> const& input)
{ return ((*this) << reinterpret_cast<boost::array<char, N> const& >(input)); }
template <std::size_t N>
bool operator<<(boost::array<signed char, N> const& input)
{ return ((*this) << reinterpret_cast<boost::array<char, N> const& >(input)); }
template <std::size_t N>
bool operator<<(boost::array<const CharT, N> const& input)
{ return shl_char_array_limited(input.begin(), N); }
template <std::size_t N>
bool operator<<(boost::array<const unsigned char, N> const& input)
{ return ((*this) << reinterpret_cast<boost::array<const char, N> const& >(input)); }
template <std::size_t N>
bool operator<<(boost::array<const signed char, N> const& input)
{ return ((*this) << reinterpret_cast<boost::array<const char, N> const& >(input)); }
#if !defined(BOOST_NO_CXX11_HDR_ARRAY) && defined(BOOST_HAS_TR1_ARRAY)
template <std::size_t N>
bool operator<<(std::array<CharT, N> const& input)
{ return shl_char_array_limited(input.begin(), N); }
template <std::size_t N>
bool operator<<(std::array<unsigned char, N> const& input)
{ return ((*this) << reinterpret_cast<boost::array<char, N> const& >(input)); }
template <std::size_t N>
bool operator<<(std::array<signed char, N> const& input)
{ return ((*this) << reinterpret_cast<boost::array<char, N> const& >(input)); }
template <std::size_t N>
bool operator<<(std::array<const CharT, N> const& input)
{ return shl_char_array_limited(input.begin(), N); }
template <std::size_t N>
bool operator<<(std::array<const unsigned char, N> const& input)
{ return ((*this) << reinterpret_cast<boost::array<const char, N> const& >(input)); }
template <std::size_t N>
bool operator<<(std::array<const signed char, N> const& input)
{ return ((*this) << reinterpret_cast<boost::array<const char, N> const& >(input)); }
#endif // !defined(BOOST_NO_CXX11_HDR_ARRAY) && defined(BOOST_HAS_TR1_ARRAY)
template <class InStreamable>
bool operator<<(const InStreamable& input) { return shl_input_streamable(input); }
/************************************ HELPER FUNCTIONS FOR OPERATORS >> ( ... ) ********************************/
@@ -1674,6 +1749,70 @@ namespace boost {
template<class Alloc>
bool operator>>(::boost::container::basic_string<CharT,Traits,Alloc>& str) { str.assign(start, finish); return true; }
private:
template <std::size_t N, class ArrayT>
bool shr_std_array(ArrayT& output, boost::mpl::bool_<true> /*is_T_char_tag*/)
{
using namespace std;
const std::size_t size = finish - start;
if (size > N - 1) { // `-1` because we need to store \0 at the end
return false;
}
memcpy(output.begin(), start, size * sizeof(CharT));
*(output.begin() + size) = static_cast<CharT>(0);
return true;
}
template <std::size_t N, class ArrayT>
bool shr_std_array(ArrayT& output, boost::mpl::bool_<false> /*is_T_char_tag*/)
{
return shr_using_base_class(output); // Array consist of non character types or unmatching character type
}
public:
template <std::size_t N>
bool operator>>(boost::array<CharT, N>& output)
{
typedef boost::mpl::bool_<true> tag_type;
return shr_std_array<N>(output, tag_type());
}
template <std::size_t N>
bool operator>>(boost::array<unsigned char, N>& output)
{
return ((*this) >> reinterpret_cast<boost::array<char, N>& >(output));
}
template <std::size_t N>
bool operator>>(boost::array<signed char, N>& output)
{
return ((*this) >> reinterpret_cast<boost::array<char, N>& >(output));
}
#if !defined(BOOST_NO_CXX11_HDR_ARRAY) && defined(BOOST_HAS_TR1_ARRAY)
template <std::size_t N>
bool operator>>(std::array<CharT, N>& output)
{
typedef boost::mpl::bool_<true> tag_type;
return shr_std_array<N>(output, tag_type());
}
template <std::size_t N>
bool operator>>(std::array<unsigned char, N>& output)
{
return ((*this) >> reinterpret_cast<std::array<char, N>& >(output));
}
template <std::size_t N>
bool operator>>(std::array<signed char, N>& in)
{
return ((*this) >> reinterpret_cast<std::array<char, N>& >(output));
}
#endif // !defined(BOOST_NO_CXX11_HDR_ARRAY) && defined(BOOST_HAS_TR1_ARRAY)
/*
* case "-0" || "0" || "+0" : output = false; return true;
* case "1" || "+1": output = true; return true;
@@ -1937,11 +2076,6 @@ namespace boost {
"Your compiler does not have full support for char32_t" );
#endif
typedef detail::lcast_src_length<src > lcast_src_length;
std::size_t const src_len = lcast_src_length::value;
char_type buf[src_len + 1];
lcast_src_length::check_coverage();
typedef BOOST_DEDUCED_TYPENAME ::boost::detail::deduce_char_traits<
char_type, Target, Source
>::type traits;
@@ -1959,20 +2093,29 @@ namespace boost {
::boost::detail::is_char_or_wchar<src_char_type >::value
> is_source_input_optimized_t;
// Target type must be default constructible
Target result;
// If we have an optimized conversion for
// Source, we do not need to construct stringbuf.
const bool requires_stringbuf = ::boost::type_traits::ice_or<
is_string_widening_required_t::value,
::boost::type_traits::ice_not< is_source_input_optimized_t::value >::value
>::value;
typedef detail::lexical_stream_limited_src<char_type, traits, requires_stringbuf > interpreter_type;
detail::lexical_stream_limited_src<char_type, traits, requires_stringbuf >
interpreter(buf, buf + src_len);
typedef detail::lcast_src_length<src > lcast_src_length;
std::size_t const src_len = lcast_src_length::value;
char_type buf[src_len + 1];
lcast_src_length::check_coverage();
interpreter_type interpreter(buf, buf + src_len);
Target result;
// Disabling ADL, by directly specifying operators.
if(!(interpreter.operator <<(arg) && interpreter.operator >>(result)))
BOOST_LCAST_THROW_BAD_CAST(Source, Target);
return result;
}
};