diff DEPENDENCIES/generic/include/boost/spirit/home/karma/char/char.hpp @ 16:2665513ce2d3

Add boost headers
author Chris Cannam
date Tue, 05 Aug 2014 11:11:38 +0100
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/DEPENDENCIES/generic/include/boost/spirit/home/karma/char/char.hpp	Tue Aug 05 11:11:38 2014 +0100
@@ -0,0 +1,547 @@
+//  Copyright (c) 2001-2011 Hartmut Kaiser
+//  Copyright (c)      2010 Bryce Lelbach
+//
+//  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)
+
+#if !defined(BOOST_SPIRIT_KARMA_CHAR_FEB_21_2007_0543PM)
+#define BOOST_SPIRIT_KARMA_CHAR_FEB_21_2007_0543PM
+
+#if defined(_MSC_VER)
+#pragma once
+#endif
+
+#include <boost/spirit/home/support/common_terminals.hpp>
+#include <boost/spirit/home/support/string_traits.hpp>
+#include <boost/spirit/home/support/info.hpp>
+#include <boost/spirit/home/support/char_class.hpp>
+#include <boost/spirit/home/support/detail/get_encoding.hpp>
+#include <boost/spirit/home/support/char_set/basic_chset.hpp>
+#include <boost/spirit/home/karma/domain.hpp>
+#include <boost/spirit/home/karma/meta_compiler.hpp>
+#include <boost/spirit/home/karma/delimit_out.hpp>
+#include <boost/spirit/home/karma/char/char_generator.hpp>
+#include <boost/spirit/home/karma/auxiliary/lazy.hpp>
+#include <boost/spirit/home/karma/detail/get_casetag.hpp>
+#include <boost/spirit/home/karma/detail/generate_to.hpp>
+#include <boost/spirit/home/karma/detail/enable_lit.hpp>
+#include <boost/fusion/include/at.hpp>
+#include <boost/fusion/include/vector.hpp>
+#include <boost/fusion/include/cons.hpp>
+#include <boost/mpl/if.hpp>
+#include <boost/mpl/assert.hpp>
+#include <boost/mpl/bool.hpp>
+#include <boost/utility/enable_if.hpp>
+#include <string>
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit
+{
+    ///////////////////////////////////////////////////////////////////////////
+    // Enablers
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename CharEncoding>
+    struct use_terminal<karma::domain
+      , tag::char_code<tag::char_, CharEncoding>        // enables char_
+    > : mpl::true_ {};
+
+    template <typename CharEncoding, typename A0>
+    struct use_terminal<karma::domain
+      , terminal_ex<
+            tag::char_code<tag::char_, CharEncoding>    // enables char_('x'), char_("x")
+          , fusion::vector1<A0>
+        >
+    > : mpl::true_ {};
+
+    template <typename A0>
+    struct use_terminal<karma::domain
+          , terminal_ex<tag::lit, fusion::vector1<A0> > // enables lit('x')
+          , typename enable_if<traits::is_char<A0> >::type>
+      : mpl::true_ {};
+
+    template <typename CharEncoding, typename A0, typename A1>
+    struct use_terminal<karma::domain
+      , terminal_ex<
+            tag::char_code<tag::char_, CharEncoding>    // enables char_('a','z')
+          , fusion::vector2<A0, A1>
+        >
+    > : mpl::true_ {};
+
+    template <typename CharEncoding>                    // enables *lazy* char_('x'), char_("x")
+    struct use_lazy_terminal<
+        karma::domain
+      , tag::char_code<tag::char_, CharEncoding>
+      , 1 // arity
+    > : mpl::true_ {};
+
+    template <>
+    struct use_terminal<karma::domain, char>            // enables 'x'
+      : mpl::true_ {};
+
+    template <>
+    struct use_terminal<karma::domain, char[2]>         // enables "x"
+      : mpl::true_ {};
+
+    template <>
+    struct use_terminal<karma::domain, wchar_t>         // enables L'x'
+      : mpl::true_ {};
+
+    template <>
+    struct use_terminal<karma::domain, wchar_t[2]>      // enables L"x"
+      : mpl::true_ {};
+}}
+
+///////////////////////////////////////////////////////////////////////////////
+namespace boost { namespace spirit { namespace karma
+{
+#ifndef BOOST_SPIRIT_NO_PREDEFINED_TERMINALS
+    using spirit::lit;    // lit('x') is equivalent to 'x'
+#endif
+    using spirit::lit_type;
+
+    ///////////////////////////////////////////////////////////////////////////
+    //
+    //  any_char
+    //      generates a single character from the associated attribute
+    //
+    //      Note: this generator has to have an associated attribute
+    //
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename CharEncoding, typename Tag>
+    struct any_char
+      : char_generator<any_char<CharEncoding, Tag>, CharEncoding, Tag>
+    {
+        typedef typename CharEncoding::char_type char_type;
+        typedef CharEncoding char_encoding;
+
+        template <typename Context, typename Unused>
+        struct attribute
+        {
+            typedef char_type type;
+        };
+
+        // any_char has an attached parameter
+        template <typename Attribute, typename CharParam, typename Context>
+        bool test(Attribute const& attr, CharParam& ch, Context&) const
+        {
+            ch = CharParam(attr);
+            return true;
+        }
+
+        // any_char has no attribute attached, it needs to have been
+        // initialized from a direct literal
+        template <typename CharParam, typename Context>
+        bool test(unused_type, CharParam&, Context&) const
+        {
+            // It is not possible (doesn't make sense) to use char_ without
+            // providing any attribute, as the generator doesn't 'know' what
+            // character to output. The following assertion fires if this
+            // situation is detected in your code.
+            BOOST_SPIRIT_ASSERT_FAIL(CharParam, char_not_usable_without_attribute, ());
+            return false;
+        }
+
+        template <typename Context>
+        static info what(Context const& /*context*/)
+        {
+            return info("any-char");
+        }
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    //
+    //  literal_char
+    //      generates a single character given by a literal it was initialized
+    //      from
+    //
+    ///////////////////////////////////////////////////////////////////////////
+    template <typename CharEncoding, typename Tag, bool no_attribute>
+    struct literal_char
+      : char_generator<literal_char<CharEncoding, Tag, no_attribute>
+          , CharEncoding, Tag>
+    {
+        typedef typename CharEncoding::char_type char_type;
+        typedef CharEncoding char_encoding;
+
+        literal_char(char_type ch)
+          : ch (spirit::char_class::convert<char_encoding>::to(Tag(), ch)) 
+        {}
+
+        template <typename Context, typename Unused>
+        struct attribute
+          : mpl::if_c<no_attribute, unused_type, char_type>
+        {};
+
+        // A char_('x') which additionally has an associated attribute emits
+        // its immediate literal only if it matches the attribute, otherwise
+        // it fails.
+        // any_char has an attached parameter
+        template <typename Attribute, typename CharParam, typename Context>
+        bool test(Attribute const& attr, CharParam& ch_, Context&) const
+        {
+            // fail if attribute isn't matched my immediate literal
+            ch_ = attr;
+            return attr == ch;
+        }
+
+        // A char_('x') without any associated attribute just emits its 
+        // immediate literal
+        template <typename CharParam, typename Context>
+        bool test(unused_type, CharParam& ch_, Context&) const
+        {
+            ch_ = ch;
+            return true;
+        }
+
+        template <typename Context>
+        info what(Context const& /*context*/) const
+        {
+            return info("literal-char", char_encoding::toucs4(ch));
+        }
+
+        char_type ch;
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    // char range generator
+    template <typename CharEncoding, typename Tag>
+    struct char_range
+      : char_generator<char_range<CharEncoding, Tag>, CharEncoding, Tag>
+    {
+        typedef typename CharEncoding::char_type char_type;
+        typedef CharEncoding char_encoding;
+
+        char_range(char_type from, char_type to)
+          : from(spirit::char_class::convert<char_encoding>::to(Tag(), from))
+          , to(spirit::char_class::convert<char_encoding>::to(Tag(), to)) 
+        {}
+
+        // A char_('a', 'z') which has an associated attribute emits it only if 
+        // it matches the character range, otherwise it fails.
+        template <typename Attribute, typename CharParam, typename Context>
+        bool test(Attribute const& attr, CharParam& ch, Context&) const
+        {
+            // fail if attribute doesn't belong to character range
+            ch = attr;
+            return (from <= char_type(attr)) && (char_type(attr) <= to);
+        }
+
+        // A char_('a', 'z') without any associated attribute fails compiling
+        template <typename CharParam, typename Context>
+        bool test(unused_type, CharParam&, Context&) const
+        {
+            // It is not possible (doesn't make sense) to use char_ generators
+            // without providing any attribute, as the generator doesn't 'know'
+            // what to output. The following assertion fires if this situation
+            // is detected in your code.
+            BOOST_SPIRIT_ASSERT_FAIL(CharParam
+              , char_range_not_usable_without_attribute, ());
+            return false;
+        }
+
+        template <typename Context>
+        info what(Context& /*context*/) const
+        {
+            info result("char-range", char_encoding::toucs4(from));
+            boost::get<std::string>(result.value) += '-';
+            boost::get<std::string>(result.value) += to_utf8(char_encoding::toucs4(to));
+            return result;
+        }
+
+        char_type from, to;
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    // character set generator
+    template <typename CharEncoding, typename Tag, bool no_attribute>
+    struct char_set
+      : char_generator<char_set<CharEncoding, Tag, no_attribute>
+          , CharEncoding, Tag>
+    {
+        typedef typename CharEncoding::char_type char_type;
+        typedef CharEncoding char_encoding;
+
+        template <typename Context, typename Unused>
+        struct attribute
+          : mpl::if_c<no_attribute, unused_type, char_type>
+        {};
+
+        template <typename String>
+        char_set(String const& str)
+        {
+            typedef typename traits::char_type_of<String>::type in_type;
+
+            BOOST_SPIRIT_ASSERT_MSG((
+                (sizeof(char_type) == sizeof(in_type))
+            ), cannot_convert_string, (String));
+
+            typedef spirit::char_class::convert<char_encoding> convert_type;
+
+            char_type const* definition =
+                (char_type const*)traits::get_c_string(str);
+            char_type ch = convert_type::to(Tag(), *definition++);
+            while (ch)
+            {
+                char_type next = convert_type::to(Tag(), *definition++);
+                if (next == '-')
+                {
+                    next = convert_type::to(Tag(), *definition++);
+                    if (next == 0)
+                    {
+                        chset.set(ch);
+                        chset.set('-');
+                        break;
+                    }
+                    chset.set(ch, next);
+                }
+                else
+                {
+                    chset.set(ch);
+                }
+                ch = next;
+            }
+        }
+
+        // A char_("a-z") which has an associated attribute emits it only if 
+        // it matches the character set, otherwise it fails.
+        template <typename Attribute, typename CharParam, typename Context>
+        bool test(Attribute const& attr, CharParam& ch, Context&) const
+        {
+            // fail if attribute doesn't belong to character set
+            ch = attr;
+            return chset.test(char_type(attr));
+        }
+
+        // A char_("a-z") without any associated attribute fails compiling
+        template <typename CharParam, typename Context>
+        bool test(unused_type, CharParam&, Context&) const
+        {
+            // It is not possible (doesn't make sense) to use char_ generators
+            // without providing any attribute, as the generator doesn't 'know'
+            // what to output. The following assertion fires if this situation
+            // is detected in your code.
+            BOOST_SPIRIT_ASSERT_FAIL(CharParam
+               , char_set_not_usable_without_attribute, ());
+            return false;
+        }
+
+        template <typename Context>
+        info what(Context& /*context*/) const
+        {
+            return info("char-set");
+        }
+
+        support::detail::basic_chset<char_type> chset;
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    // Generator generators: make_xxx function (objects)
+    ///////////////////////////////////////////////////////////////////////////
+    namespace detail
+    {
+        template <typename Modifiers, typename Encoding>
+        struct basic_literal
+        {
+            static bool const lower =
+                has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value;
+            static bool const upper =
+                has_modifier<Modifiers, tag::char_code_base<tag::upper> >::value;
+
+            typedef literal_char<
+                typename spirit::detail::get_encoding_with_case<
+                    Modifiers, Encoding, lower || upper>::type
+              , typename get_casetag<Modifiers, lower || upper>::type
+              , true>
+            result_type;
+
+            template <typename Char>
+            result_type operator()(Char ch, unused_type) const
+            {
+                return result_type(ch);
+            }
+
+            template <typename Char>
+            result_type operator()(Char const* str, unused_type) const
+            {
+                return result_type(str[0]);
+            }
+        };
+    }
+
+    // literals: 'x', "x"
+    template <typename Modifiers>
+    struct make_primitive<char, Modifiers>
+      : detail::basic_literal<Modifiers, char_encoding::standard> {};
+
+    template <typename Modifiers>
+    struct make_primitive<char const(&)[2], Modifiers>
+      : detail::basic_literal<Modifiers, char_encoding::standard> {};
+
+    // literals: L'x', L"x"
+    template <typename Modifiers>
+    struct make_primitive<wchar_t, Modifiers>
+      : detail::basic_literal<Modifiers, char_encoding::standard_wide> {};
+
+    template <typename Modifiers>
+    struct make_primitive<wchar_t const(&)[2], Modifiers>
+      : detail::basic_literal<Modifiers, char_encoding::standard_wide> {};
+
+    // char_
+    template <typename CharEncoding, typename Modifiers>
+    struct make_primitive<tag::char_code<tag::char_, CharEncoding>, Modifiers>
+    {
+        static bool const lower =
+            has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value;
+        static bool const upper =
+            has_modifier<Modifiers, tag::char_code_base<tag::upper> >::value;
+
+        typedef any_char<
+            typename spirit::detail::get_encoding_with_case<
+                Modifiers, CharEncoding, lower || upper>::type
+          , typename detail::get_casetag<Modifiers, lower || upper>::type
+        > result_type;
+
+        result_type operator()(unused_type, unused_type) const
+        {
+            return result_type();
+        }
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    namespace detail
+    {
+        template <typename CharEncoding, typename Modifiers, typename A0
+          , bool no_attribute>
+        struct make_char_direct
+        {
+            static bool const lower =
+                has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value;
+            static bool const upper =
+                has_modifier<Modifiers, tag::char_code_base<tag::upper> >::value;
+
+            typedef typename spirit::detail::get_encoding_with_case<
+                Modifiers, CharEncoding, lower || upper>::type encoding;
+            typedef typename detail::get_casetag<
+                Modifiers, lower || upper>::type tag;
+
+            typedef typename mpl::if_<
+                traits::is_string<A0>
+              , char_set<encoding, tag, no_attribute>
+              , literal_char<encoding, tag, no_attribute>
+            >::type result_type;
+
+            template <typename Terminal>
+            result_type operator()(Terminal const& term, unused_type) const
+            {
+                return result_type(fusion::at_c<0>(term.args));
+            }
+        };
+    }
+
+    // char_(...), lit(...)
+    template <typename CharEncoding, typename Modifiers, typename A0>
+    struct make_primitive<
+            terminal_ex<
+                tag::char_code<tag::char_, CharEncoding>
+              , fusion::vector1<A0> >
+          , Modifiers>
+      : detail::make_char_direct<CharEncoding, Modifiers, A0, false>
+    {};
+
+    template <typename Modifiers, typename A0>
+    struct make_primitive<
+            terminal_ex<tag::lit, fusion::vector1<A0> >
+          , Modifiers
+          , typename enable_if<traits::is_char<A0> >::type>
+      : detail::make_char_direct<
+            typename traits::char_encoding_from_char<
+                typename traits::char_type_of<A0>::type>::type
+          , Modifiers, A0, true>
+    {};
+
+    ///////////////////////////////////////////////////////////////////////////
+    // char_("x")
+    template <typename CharEncoding, typename Modifiers, typename Char>
+    struct make_primitive<
+        terminal_ex<
+            tag::char_code<tag::char_, CharEncoding>
+          , fusion::vector1<Char(&)[2]> > // For single char strings
+      , Modifiers>
+    {
+        static bool const lower =
+            has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value;
+        static bool const upper =
+            has_modifier<Modifiers, tag::char_code_base<tag::upper> >::value;
+
+        typedef literal_char<
+            typename spirit::detail::get_encoding_with_case<
+                Modifiers, CharEncoding, lower || upper>::type
+          , typename detail::get_casetag<Modifiers, lower || upper>::type
+          , false
+        > result_type;
+
+        template <typename Terminal>
+        result_type operator()(Terminal const& term, unused_type) const
+        {
+            return result_type(fusion::at_c<0>(term.args)[0]);
+        }
+    };
+
+    ///////////////////////////////////////////////////////////////////////////
+    // char_('a', 'z')
+    template <typename CharEncoding, typename Modifiers, typename A0, typename A1>
+    struct make_primitive<
+        terminal_ex<
+            tag::char_code<tag::char_, CharEncoding>
+          , fusion::vector2<A0, A1>
+        >
+      , Modifiers>
+    {
+        static bool const lower =
+            has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value;
+        static bool const upper =
+            has_modifier<Modifiers, tag::char_code_base<tag::upper> >::value;
+
+        typedef char_range<
+            typename spirit::detail::get_encoding_with_case<
+                Modifiers, CharEncoding, lower || upper>::type
+          , typename detail::get_casetag<Modifiers, lower || upper>::type
+        > result_type;
+
+        template <typename Terminal>
+        result_type operator()(Terminal const& term, unused_type) const
+        {
+            return result_type(fusion::at_c<0>(term.args)
+              , fusion::at_c<1>(term.args));
+        }
+    };
+
+    template <typename CharEncoding, typename Modifiers, typename Char>
+    struct make_primitive<
+        terminal_ex<
+            tag::char_code<tag::char_, CharEncoding>
+          , fusion::vector2<Char(&)[2], Char(&)[2]> // For single char strings
+        >
+      , Modifiers>
+    {
+        static bool const lower =
+            has_modifier<Modifiers, tag::char_code_base<tag::lower> >::value;
+        static bool const upper =
+            has_modifier<Modifiers, tag::char_code_base<tag::upper> >::value;
+
+        typedef char_range<
+            typename spirit::detail::get_encoding_with_case<
+                Modifiers, CharEncoding, lower || upper>::type
+          , typename detail::get_casetag<Modifiers, lower || upper>::type
+        > result_type;
+
+        template <typename Terminal>
+        result_type operator()(Terminal const& term, unused_type) const
+        {
+            return result_type(fusion::at_c<0>(term.args)[0]
+              , fusion::at_c<1>(term.args)[0]);
+        }
+    };
+}}}   // namespace boost::spirit::karma
+
+#endif