boost/xpressive/detail/static/as_xpr.hpp
///////////////////////////////////////////////////////////////////////////////
// as_xpr.hpp
//
// Copyright 2004 Eric Niebler. 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)
#ifndef BOOST_XPRESSIVE_DETAIL_STATIC_AS_XPR_HPP_EAN_10_04_2005
#define BOOST_XPRESSIVE_DETAIL_STATIC_AS_XPR_HPP_EAN_10_04_2005
// MS compatible compilers support #pragma once
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
#include <boost/ref.hpp>
#include <boost/mpl/if.hpp>
#include <boost/mpl/assert.hpp>
#include <boost/mpl/identity.hpp>
#include <boost/mpl/apply.hpp>
#include <boost/mpl/placeholders.hpp>
#include <boost/mpl/eval_if.hpp>
#include <boost/mpl/logical.hpp>
#include <boost/type_traits/is_array.hpp>
#include <boost/type_traits/remove_bounds.hpp>
#include <boost/type_traits/remove_pointer.hpp>
#include <boost/type_traits/is_convertible.hpp>
#include <boost/xpressive/detail/detail_fwd.hpp>
#include <boost/xpressive/proto/proto.hpp>
#include <boost/xpressive/detail/static/placeholders.hpp>
namespace boost { namespace xpressive { namespace detail
{
template<typename T>
struct wrap { wrap(T); };
///////////////////////////////////////////////////////////////////////////////
// is_string_literal
//
template<typename T>
struct is_string_literal
: mpl::or_
<
is_convertible<T, wrap<char const *> >
, is_convertible<T, wrap<wchar_t const *> >
>
{
};
///////////////////////////////////////////////////////////////////////////////
// string_generator
//
template<typename String>
struct string_placeholder_generator
{
typedef typename remove_cv
<
typename mpl::eval_if
<
is_array<String>
, remove_bounds<String>
, remove_pointer<String>
>::type
>::type char_type;
typedef string_placeholder<char_type> type;
};
///////////////////////////////////////////////////////////////////////////////
// as_matcher
template<typename Matcher, bool IsXpr = is_xpr<Matcher>::value>
struct as_matcher_type
{
typedef Matcher type;
static type const &call(Matcher const &matcher)
{
return matcher;
}
};
template<typename Literal>
struct as_matcher_type<Literal, false>
{
typedef typename mpl::eval_if
<
is_string_literal<Literal>
, string_placeholder_generator<Literal>
, mpl::identity<literal_placeholder<Literal, false> >
>::type type;
static type call(Literal const &literal)
{
return type(literal);
}
};
template<typename BidiIter>
struct as_matcher_type<basic_regex<BidiIter>, false>
{
typedef regex_placeholder<BidiIter, false> type;
static type call(basic_regex<BidiIter> const &rex)
{
typedef core_access<BidiIter> access;
shared_ptr<regex_impl<BidiIter> > impl = access::get_regex_impl(rex);
return type(impl);
}
};
template<typename BidiIter>
struct as_matcher_type<reference_wrapper<basic_regex<BidiIter> const>, false>
{
typedef regex_placeholder<BidiIter, false> type;
static type call(reference_wrapper<basic_regex<BidiIter> const> const &rex)
{
typedef core_access<BidiIter> access;
shared_ptr<regex_impl<BidiIter> > impl = access::get_regex_impl(rex.get());
return type(impl);
}
};
///////////////////////////////////////////////////////////////////////////////
// as_xpr_type
//
template<typename Xpr>
struct as_xpr_type<Xpr, true> // is_op == true
{
typedef Xpr type;
typedef Xpr const &const_reference;
static Xpr const &call(Xpr const &xpr)
{
return xpr;
}
};
template<typename Xpr>
struct as_xpr_type<Xpr, false>
{
typedef proto::unary_op
<
typename as_matcher_type<Xpr>::type
, proto::noop_tag
> type;
typedef type const const_reference;
static type const call(Xpr const &xpr)
{
return proto::noop(detail::as_matcher_type<Xpr>::call(xpr));
}
};
}}} // namespace boost::xpressive::detail
namespace boost { namespace xpressive
{
///////////////////////////////////////////////////////////////////////////////
// as_xpr (from a literal to an xpression)
//
template<typename Xpr>
inline typename detail::as_xpr_type<Xpr>::const_reference
as_xpr(Xpr const &xpr)
{
return detail::as_xpr_type<Xpr>::call(xpr);
}
}} // namespace boost::xpressive
#endif