forked from boostorg/range
Merge branch 'develop' to incorporate the formatted adaptor
This commit is contained in:
0
include/boost/range/adaptor/argument_fwd.hpp
Executable file → Normal file
0
include/boost/range/adaptor/argument_fwd.hpp
Executable file → Normal file
0
include/boost/range/adaptor/copied.hpp
Executable file → Normal file
0
include/boost/range/adaptor/copied.hpp
Executable file → Normal file
0
include/boost/range/adaptor/filtered.hpp
Executable file → Normal file
0
include/boost/range/adaptor/filtered.hpp
Executable file → Normal file
229
include/boost/range/adaptor/formatted.hpp
Normal file
229
include/boost/range/adaptor/formatted.hpp
Normal file
@ -0,0 +1,229 @@
|
||||
// Boost.Range library
|
||||
//
|
||||
// Copyright Neil Groves 2014.
|
||||
// Use, modification and distribution is subject to 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)
|
||||
//
|
||||
// For more information, see http://www.boost.org/libs/range/
|
||||
//
|
||||
#ifndef BOOST_RANGE_ADAPTOR_FORMATTED_HPP_INCLUDED
|
||||
#define BOOST_RANGE_ADAPTOR_FORMATTED_HPP_INCLUDED
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/range/concepts.hpp>
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
#include <boost/range/iterator.hpp>
|
||||
#include <boost/range/iterator_range_core.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/type_traits/is_array.hpp>
|
||||
#include <boost/type_traits/remove_extent.hpp>
|
||||
#include <ostream>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace range_detail
|
||||
{
|
||||
|
||||
template<typename Sep, typename Prefix, typename Postfix>
|
||||
struct formatted_holder
|
||||
{
|
||||
typedef typename boost::mpl::if_<
|
||||
boost::is_array<Sep>,
|
||||
const typename boost::remove_extent<Sep>::type*,
|
||||
Sep
|
||||
>::type separator_t;
|
||||
|
||||
typedef typename boost::mpl::if_<
|
||||
boost::is_array<Prefix>,
|
||||
const typename boost::remove_extent<Prefix>::type*,
|
||||
Prefix
|
||||
>::type prefix_t;
|
||||
|
||||
typedef typename boost::mpl::if_<
|
||||
boost::is_array<Postfix>,
|
||||
const typename boost::remove_extent<Postfix>::type*,
|
||||
Postfix
|
||||
>::type postfix_t;
|
||||
|
||||
formatted_holder(
|
||||
const separator_t& sep,
|
||||
const prefix_t& prefix,
|
||||
const postfix_t& postfix)
|
||||
: m_sep(sep)
|
||||
, m_prefix(prefix)
|
||||
, m_postfix(postfix)
|
||||
{
|
||||
}
|
||||
|
||||
separator_t m_sep;
|
||||
prefix_t m_prefix;
|
||||
postfix_t m_postfix;
|
||||
};
|
||||
|
||||
template<typename Iter, typename Sep, typename Prefix, typename Postfix>
|
||||
class formatted_range
|
||||
: public boost::iterator_range<Iter>
|
||||
{
|
||||
typedef formatted_holder<Sep,Prefix,Postfix> holder_t;
|
||||
public:
|
||||
formatted_range(Iter first, Iter last, const holder_t& holder)
|
||||
: boost::iterator_range<Iter>(first, last)
|
||||
, m_holder(holder)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename OStream>
|
||||
void write(OStream& out) const
|
||||
{
|
||||
Iter it(this->begin());
|
||||
out << m_holder.m_prefix;
|
||||
if (it != this->end())
|
||||
{
|
||||
out << *it;
|
||||
for (++it; it != this->end(); ++it)
|
||||
{
|
||||
out << m_holder.m_sep << *it;
|
||||
}
|
||||
}
|
||||
out << m_holder.m_postfix;
|
||||
}
|
||||
|
||||
private:
|
||||
holder_t m_holder;
|
||||
};
|
||||
|
||||
template<
|
||||
typename SinglePassRange,
|
||||
typename Sep,
|
||||
typename Prefix,
|
||||
typename Postfix
|
||||
>
|
||||
inline range_detail::formatted_range<
|
||||
typename range_iterator<const SinglePassRange>::type, Sep, Prefix, Postfix
|
||||
>
|
||||
operator|(
|
||||
const SinglePassRange& rng,
|
||||
const range_detail::formatted_holder<Sep,Prefix,Postfix>& holder
|
||||
)
|
||||
{
|
||||
typedef typename range_iterator<const SinglePassRange>::type iterator;
|
||||
return range_detail::formatted_range<iterator, Sep, Prefix, Postfix>(
|
||||
boost::begin(rng), boost::end(rng), holder);
|
||||
}
|
||||
|
||||
template<typename Char, typename Traits, typename Iter, typename Sep,
|
||||
typename Prefix, typename Postfix>
|
||||
std::basic_ostream<Char, Traits>&
|
||||
operator<<(
|
||||
std::basic_ostream<Char, Traits>& out,
|
||||
const formatted_range<Iter, Sep, Prefix, Postfix>& writer)
|
||||
{
|
||||
writer.write(out);
|
||||
return out;
|
||||
}
|
||||
|
||||
} // namespace range_detail
|
||||
|
||||
namespace adaptors
|
||||
{
|
||||
|
||||
template<typename Sep, typename Prefix, typename Postfix>
|
||||
range_detail::formatted_holder<Sep, Prefix, Postfix>
|
||||
formatted(const Sep& sep, const Prefix& prefix, const Postfix& postfix)
|
||||
{
|
||||
return range_detail::formatted_holder<Sep,Prefix,Postfix>(
|
||||
sep, prefix, postfix);
|
||||
}
|
||||
|
||||
template<typename Sep, typename Prefix>
|
||||
range_detail::formatted_holder<Sep, Prefix, char>
|
||||
formatted(const Sep& sep, const Prefix& prefix)
|
||||
{
|
||||
return range_detail::formatted_holder<Sep, Prefix, char>(sep, prefix, '}');
|
||||
}
|
||||
|
||||
template<typename Sep>
|
||||
range_detail::formatted_holder<Sep, char, char>
|
||||
formatted(const Sep& sep)
|
||||
{
|
||||
return range_detail::formatted_holder<Sep, char, char>(sep, '{', '}');
|
||||
}
|
||||
|
||||
range_detail::formatted_holder<char, char, char>
|
||||
formatted()
|
||||
{
|
||||
return range_detail::formatted_holder<char, char, char>(',', '{', '}');
|
||||
}
|
||||
|
||||
using range_detail::formatted_range;
|
||||
|
||||
template<typename SinglePassRange, typename Sep, typename Prefix,
|
||||
typename Postfix>
|
||||
inline boost::range_detail::formatted_range<
|
||||
typename boost::range_iterator<const SinglePassRange>::type,
|
||||
Sep, Prefix, Postfix
|
||||
>
|
||||
format(
|
||||
const SinglePassRange& rng,
|
||||
const Sep& sep,
|
||||
const Prefix& prefix,
|
||||
const Postfix& postfix
|
||||
)
|
||||
{
|
||||
typedef typename boost::range_iterator<const SinglePassRange>::type
|
||||
iterator_t;
|
||||
|
||||
typedef boost::range_detail::formatted_range<
|
||||
iterator_t, Sep, Prefix, Postfix> result_t;
|
||||
|
||||
typedef boost::range_detail::formatted_holder<Sep, Prefix, Postfix>
|
||||
holder_t;
|
||||
|
||||
return result_t(boost::begin(rng), boost::end(rng),
|
||||
holder_t(sep, prefix, postfix));
|
||||
}
|
||||
|
||||
template<typename SinglePassRange, typename Sep, typename Prefix>
|
||||
inline boost::range_detail::formatted_range<
|
||||
typename boost::range_iterator<const SinglePassRange>::type,
|
||||
Sep, Prefix, char
|
||||
>
|
||||
format(
|
||||
const SinglePassRange& rng,
|
||||
const Sep& sep,
|
||||
const Prefix& prefix)
|
||||
{
|
||||
return adaptors::format<SinglePassRange, Sep, Prefix, char>(rng, sep, prefix, '}');
|
||||
}
|
||||
|
||||
template<typename SinglePassRange, typename Sep>
|
||||
inline boost::range_detail::formatted_range<
|
||||
typename boost::range_iterator<const SinglePassRange>::type,
|
||||
Sep, char, char
|
||||
>
|
||||
format(const SinglePassRange& rng, const Sep& sep)
|
||||
{
|
||||
return adaptors::format<SinglePassRange, Sep, char, char>(rng, sep, '{', '}');
|
||||
}
|
||||
|
||||
template<typename SinglePassRange>
|
||||
inline boost::range_detail::formatted_range<
|
||||
typename boost::range_iterator<const SinglePassRange>::type,
|
||||
char, char, char
|
||||
>
|
||||
format(const SinglePassRange& rng)
|
||||
{
|
||||
return adaptors::format<SinglePassRange, char, char, char>(rng, ',', '{', '}');
|
||||
}
|
||||
|
||||
} // namespace adaptors
|
||||
|
||||
namespace range
|
||||
{
|
||||
using boost::range_detail::formatted_range;
|
||||
} // namespace range
|
||||
} // namespace boost
|
||||
|
||||
#endif // include guard
|
0
include/boost/range/adaptor/map.hpp
Executable file → Normal file
0
include/boost/range/adaptor/map.hpp
Executable file → Normal file
0
include/boost/range/adaptor/reversed.hpp
Executable file → Normal file
0
include/boost/range/adaptor/reversed.hpp
Executable file → Normal file
0
include/boost/range/adaptor/sliced.hpp
Executable file → Normal file
0
include/boost/range/adaptor/sliced.hpp
Executable file → Normal file
0
include/boost/range/adaptor/uniqued.hpp
Executable file → Normal file
0
include/boost/range/adaptor/uniqued.hpp
Executable file → Normal file
@ -15,6 +15,7 @@
|
||||
#include <boost/range/adaptor/adjacent_filtered.hpp>
|
||||
#include <boost/range/adaptor/copied.hpp>
|
||||
#include <boost/range/adaptor/filtered.hpp>
|
||||
#include <boost/range/adaptor/formatted.hpp>
|
||||
#include <boost/range/adaptor/indexed.hpp>
|
||||
#include <boost/range/adaptor/indirected.hpp>
|
||||
#include <boost/range/adaptor/map.hpp>
|
||||
|
@ -64,6 +64,7 @@ namespace boost {
|
||||
#ifndef BOOST_RANGE_ENABLE_CONCEPT_ASSERT
|
||||
|
||||
// List broken compiler versions here:
|
||||
#ifndef __clang__
|
||||
#ifdef __GNUC__
|
||||
// GNUC 4.2 has strange issues correctly detecting compliance with the Concepts
|
||||
// hence the least disruptive approach is to turn-off the concept checking for
|
||||
@ -79,6 +80,7 @@ namespace boost {
|
||||
#define BOOST_RANGE_ENABLE_CONCEPT_ASSERT 0
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#define BOOST_RANGE_ENABLE_CONCEPT_ASSERT 0
|
||||
|
@ -1,94 +0,0 @@
|
||||
// Boost.Range library
|
||||
//
|
||||
// Copyright Neil Groves 2014.
|
||||
// Use, modification and distribution is subject to 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)
|
||||
//
|
||||
// For more information, see http://www.boost.org/libs/range/
|
||||
//
|
||||
#ifndef BOOST_RANGE_SEPARATED_HPP_INCLUDED
|
||||
#define BOOST_RANGE_SEPARATED_HPP_INCLUDED
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/range/concepts.hpp>
|
||||
#include <boost/range/begin.hpp>
|
||||
#include <boost/range/end.hpp>
|
||||
#include <boost/range/iterator.hpp>
|
||||
#include <ostream>
|
||||
|
||||
namespace boost
|
||||
{
|
||||
namespace range_detail
|
||||
{
|
||||
|
||||
template<typename Iter, typename Separator>
|
||||
class output_stream_writer
|
||||
{
|
||||
public:
|
||||
output_stream_writer(Iter first, Iter last, Separator separator)
|
||||
: m_first(first)
|
||||
, m_last(last)
|
||||
, m_separator(separator)
|
||||
{
|
||||
}
|
||||
|
||||
template<typename OStream>
|
||||
void write(OStream& out) const
|
||||
{
|
||||
write_impl(out, m_first, m_last, m_separator);
|
||||
}
|
||||
|
||||
private:
|
||||
template<typename OStream>
|
||||
static void write_impl(
|
||||
OStream& out, Iter first, Iter last, Separator separator)
|
||||
{
|
||||
if (first != last)
|
||||
{
|
||||
out << *first;
|
||||
for (++first; first != last; ++first)
|
||||
{
|
||||
out << separator << *first;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Iter m_first;
|
||||
Iter m_last;
|
||||
Separator m_separator;
|
||||
};
|
||||
|
||||
template<typename Char, typename Traits, typename Iter, typename Separator>
|
||||
std::basic_ostream<Char, Traits>&
|
||||
operator<<(
|
||||
std::basic_ostream<Char, Traits>& out,
|
||||
const output_stream_writer<Iter, Separator>& writer)
|
||||
{
|
||||
writer.write(out);
|
||||
return out;
|
||||
}
|
||||
|
||||
} // namespace range_detail
|
||||
|
||||
namespace range
|
||||
{
|
||||
|
||||
template<typename Range, typename Separator>
|
||||
inline range_detail::output_stream_writer<
|
||||
typename range_iterator<const Range>::type,
|
||||
Separator
|
||||
>
|
||||
separated(const Range& rng, Separator separator)
|
||||
{
|
||||
BOOST_RANGE_CONCEPT_ASSERT((SinglePassRangeConcept<const Range>));
|
||||
return range_detail::output_stream_writer<
|
||||
typename range_iterator<const Range>::type,
|
||||
Separator
|
||||
>(boost::begin(rng), boost::end(rng), separator);
|
||||
}
|
||||
|
||||
} // namespace range
|
||||
} // namespace boost
|
||||
|
||||
#endif // include guard
|
Reference in New Issue
Block a user