Porting from qi::symbols to x3::symbols_parser

classic Classic list List threaded Threaded
12 messages Options
Reply | Threaded
Open this post in threaded view
|

Porting from qi::symbols to x3::symbols_parser

Mario Lang
Hi.

In my Qi based project, I have a custom symbols class that looks like
this:

struct tst_braillify {
  template <typename Char>
  Char operator()(Char ch) const {
    return 0X2800 | get_dots_for_character(ch);
  }
};

template <typename T = boost::spirit::unused_type>
struct brl_symbols : boost::spirit::qi::symbols<
    wchar_t, T, boost::spirit::qi::tst<wchar_t, T>, tst_braillify
>
{};

Trying to port this to X3, I notice that the Filter template parameter
is no longer present in x3::symbols_parser (vs. qi::symbols).

It now seems to be internally used to handle case comparison.

Am I missing something, or is the ability to provide a custom Filter
gone now?  What should I do to implement similar behaviour in an X3
based parser?

--
CYa,
  ⡍⠁⠗⠊⠕

------------------------------------------------------------------------------
One dashboard for servers and applications across Physical-Virtual-Cloud
Widest out-of-the-box monitoring support with 50+ applications
Performance metrics, stats and reports that give you Actionable Insights
Deep dive visibility with transaction tracing using APM Insight.
http://ad.doubleclick.net/ddm/clk/290420510;117567292;y
_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general
Reply | Threaded
Open this post in threaded view
|

Re: Porting from qi::symbols to x3::symbols_parser

Joel de Guzman
On 5/21/15 9:26 PM, Mario Lang wrote:

> Hi.
>
> In my Qi based project, I have a custom symbols class that looks like
> this:
>
> struct tst_braillify {
>    template <typename Char>
>    Char operator()(Char ch) const {
>      return 0X2800 | get_dots_for_character(ch);
>    }
> };
>
> template <typename T = boost::spirit::unused_type>
> struct brl_symbols : boost::spirit::qi::symbols<
>      wchar_t, T, boost::spirit::qi::tst<wchar_t, T>, tst_braillify
>>
> {};
>
> Trying to port this to X3, I notice that the Filter template parameter
> is no longer present in x3::symbols_parser (vs. qi::symbols).
>
> It now seems to be internally used to handle case comparison.
>
> Am I missing something, or is the ability to provide a custom Filter
> gone now?  What should I do to implement similar behaviour in an X3
> based parser?

I guess I tried to hard at simplification. I never thought anyone was using
that. It is not even documented:

 
http://www.boost.org/doc/libs/1_57_0/libs/spirit/doc/html/spirit/qi/reference/string/symbols.html

OK, here's the deal: port it back and I'll use the forward port as long
as all tests pass. Deal? Oh and one more thing, you'll also have to
add the docs for this "Filter" for it once we're there :-)

Regards,
--
Joel de Guzman
http://www.ciere.com
http://boost-spirit.com
http://www.cycfi.com/


------------------------------------------------------------------------------
One dashboard for servers and applications across Physical-Virtual-Cloud
Widest out-of-the-box monitoring support with 50+ applications
Performance metrics, stats and reports that give you Actionable Insights
Deep dive visibility with transaction tracing using APM Insight.
http://ad.doubleclick.net/ddm/clk/290420510;117567292;y
_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general
Reply | Threaded
Open this post in threaded view
|

Re: Porting from qi::symbols to x3::symbols_parser

teajay-2
Le 21/05/2015 15:59, Joel de Guzman a écrit :

> On 5/21/15 9:26 PM, Mario Lang wrote:
>> Hi.
>>
>> In my Qi based project, I have a custom symbols class that looks like
>> this:
>>
>> struct tst_braillify {
>>     template <typename Char>
>>     Char operator()(Char ch) const {
>>       return 0X2800 | get_dots_for_character(ch);
>>     }
>> };
>>
>> template <typename T = boost::spirit::unused_type>
>> struct brl_symbols : boost::spirit::qi::symbols<
>>       wchar_t, T, boost::spirit::qi::tst<wchar_t, T>, tst_braillify
>>>
>> {};
>>
>> Trying to port this to X3, I notice that the Filter template parameter
>> is no longer present in x3::symbols_parser (vs. qi::symbols).
>>
>> It now seems to be internally used to handle case comparison.
>>
>> Am I missing something, or is the ability to provide a custom Filter
>> gone now?  What should I do to implement similar behaviour in an X3
>> based parser?
>
> I guess I tried to hard at simplification. I never thought anyone was using
> that. It is not even documented:
>
>
> http://www.boost.org/doc/libs/1_57_0/libs/spirit/doc/html/spirit/qi/reference/string/symbols.html
>
> OK, here's the deal: port it back and I'll use the forward port as long
> as all tests pass. Deal? Oh and one more thing, you'll also have to
> add the docs for this "Filter" for it once we're there :-)
>
> Regards,
>

The filter is not completly gone. It's still there but is used only
internally for case insensitive parsing, like this:


     if (value_type* val_ptr
       = lookup->find(first, last, get_case_compare<Encoding>(context)))

from symbols.hpp.

Right now the filter is fetched through the get_case_compare template
according to the encoding, so maybe you could define a custom encoding
and customize the get_case_compare template to return the correct filter.

Hope this helps.

Regards,

Thomas Bernard

------------------------------------------------------------------------------
One dashboard for servers and applications across Physical-Virtual-Cloud
Widest out-of-the-box monitoring support with 50+ applications
Performance metrics, stats and reports that give you Actionable Insights
Deep dive visibility with transaction tracing using APM Insight.
http://ad.doubleclick.net/ddm/clk/290420510;117567292;y
_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general
Reply | Threaded
Open this post in threaded view
|

Re: Porting from qi::symbols to x3::symbols_parser

Mario Lang
teajay <[hidden email]> writes:

> Le 21/05/2015 15:59, Joel de Guzman a écrit :
>> On 5/21/15 9:26 PM, Mario Lang wrote:
>>> In my Qi based project, I have a custom symbols class that looks like
>>> this:
>>>
>>> struct tst_braillify {
>>>     template <typename Char>
>>>     Char operator()(Char ch) const {
>>>       return 0X2800 | get_dots_for_character(ch);
>>>     }
>>> };
>>>
>>> template <typename T = boost::spirit::unused_type>
>>> struct brl_symbols : boost::spirit::qi::symbols<
>>>       wchar_t, T, boost::spirit::qi::tst<wchar_t, T>, tst_braillify
>>>>
>>> {};
>>>
>>> Trying to port this to X3, I notice that the Filter template parameter
>>> is no longer present in x3::symbols_parser (vs. qi::symbols).
>>>
>>> It now seems to be internally used to handle case comparison.
>>>
>>> Am I missing something, or is the ability to provide a custom Filter
>>> gone now?  What should I do to implement similar behaviour in an X3
>>> based parser?
>>
>> I guess I tried to hard at simplification. I never thought anyone was using
>> that. It is not even documented:
>>
>>
>> http://www.boost.org/doc/libs/1_57_0/libs/spirit/doc/html/spirit/qi/reference/string/symbols.html
>>
>> OK, here's the deal: port it back and I'll use the forward port as long
>> as all tests pass. Deal? Oh and one more thing, you'll also have to
>> add the docs for this "Filter" for it once we're there :-)
>
> The filter is not completly gone. It's still there but is used only
> internally for case insensitive parsing, like this:
>
>      if (value_type* val_ptr
>        = lookup->find(first, last, get_case_compare<Encoding>(context)))
>
> from symbols.hpp.
>
> Right now the filter is fetched through the get_case_compare template
> according to the encoding, so maybe you could define a custom encoding
> and customize the get_case_compare template to return the correct filter.

Nice hint.  However, I think this is not possible, because:

cc.cpp:33:71: error: non-class, non-variable partial specialization ‘get_case_compare<braille::encoding::dots, Context>’ is not allowed

#include <boost/spirit/home/x3.hpp>

namespace braille {
    namespace encoding {
        struct dots
        {
            using char_type = char32_t;
        };
    }

    template <typename Encoding>
    struct dots_compare
    {
        int32_t operator()(
              typename Encoding::char_type const lc
            , typename Encoding::char_type const rc) const
        {
            // do magic here
            return lc - rc;
        }

        template <typename CharClassTag>
        CharClassTag get_char_class_tag(CharClassTag tag) const
        {
            return tag;
        }
    };
}

namespace boost { namespace spirit { namespace x3 {
    template <typename Context>
    braille::dots_compare<braille::encoding::dots>
    get_case_compare<braille::encoding::dots, Context>(Context const &)
    {
        return {};
    }
}}}

namespace braille {
    template<typename T = boost::spirit::x3::unused_type>
    using symbols = boost::spirit::x3::symbols_parser<braille::encoding::dots, T>;
}

int main()
{
    braille::symbols<> syms;
    syms.add(U"\u2800");
    std::u32string input = U" ";
    std::u32string::const_iterator iter = input.begin();
    std::u32string::const_iterator const end = input.end();
    bool const success = parse(iter, end, syms);
    return success;
}


--
CYa,
  ⡍⠁⠗⠊⠕

------------------------------------------------------------------------------
One dashboard for servers and applications across Physical-Virtual-Cloud
Widest out-of-the-box monitoring support with 50+ applications
Performance metrics, stats and reports that give you Actionable Insights
Deep dive visibility with transaction tracing using APM Insight.
http://ad.doubleclick.net/ddm/clk/290420510;117567292;y
_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general
Reply | Threaded
Open this post in threaded view
|

Re: Porting from qi::symbols to x3::symbols_parser

teajay-2


Le 21/05/2015 23:55, Mario Lang a écrit :

> teajay <[hidden email]> writes:
>
>> Le 21/05/2015 15:59, Joel de Guzman a écrit :
>>> On 5/21/15 9:26 PM, Mario Lang wrote:
>>>> In my Qi based project, I have a custom symbols class that looks like
>>>> this:
>>>>
>>>> struct tst_braillify {
>>>>      template <typename Char>
>>>>      Char operator()(Char ch) const {
>>>>        return 0X2800 | get_dots_for_character(ch);
>>>>      }
>>>> };
>>>>
>>>> template <typename T = boost::spirit::unused_type>
>>>> struct brl_symbols : boost::spirit::qi::symbols<
>>>>        wchar_t, T, boost::spirit::qi::tst<wchar_t, T>, tst_braillify
>>>> {};
>>>>
>>>> Trying to port this to X3, I notice that the Filter template parameter
>>>> is no longer present in x3::symbols_parser (vs. qi::symbols).
>>>>
>>>> It now seems to be internally used to handle case comparison.
>>>>
>>>> Am I missing something, or is the ability to provide a custom Filter
>>>> gone now?  What should I do to implement similar behaviour in an X3
>>>> based parser?
>>> I guess I tried to hard at simplification. I never thought anyone was using
>>> that. It is not even documented:
>>>
>>>
>>> http://www.boost.org/doc/libs/1_57_0/libs/spirit/doc/html/spirit/qi/reference/string/symbols.html
>>>
>>> OK, here's the deal: port it back and I'll use the forward port as long
>>> as all tests pass. Deal? Oh and one more thing, you'll also have to
>>> add the docs for this "Filter" for it once we're there :-)
>> The filter is not completly gone. It's still there but is used only
>> internally for case insensitive parsing, like this:
>>
>>       if (value_type* val_ptr
>>         = lookup->find(first, last, get_case_compare<Encoding>(context)))
>>
>> from symbols.hpp.
>>
>> Right now the filter is fetched through the get_case_compare template
>> according to the encoding, so maybe you could define a custom encoding
>> and customize the get_case_compare template to return the correct filter.
> Nice hint.  However, I think this is not possible, because:
>
> cc.cpp:33:71: error: non-class, non-variable partial specialization ‘get_case_compare<braille::encoding::dots, Context>’ is not allowed
>
> #include <boost/spirit/home/x3.hpp>
>
> namespace braille {
>      namespace encoding {
>          struct dots
>          {
>              using char_type = char32_t;
>          };
>      }
>
>      template <typename Encoding>
>      struct dots_compare
>      {
>          int32_t operator()(
>                typename Encoding::char_type const lc
>              , typename Encoding::char_type const rc) const
>          {
>              // do magic here
>              return lc - rc;
>          }
>
>          template <typename CharClassTag>
>          CharClassTag get_char_class_tag(CharClassTag tag) const
>          {
>              return tag;
>          }
>      };
> }
>
> namespace boost { namespace spirit { namespace x3 {
>      template <typename Context>
>      braille::dots_compare<braille::encoding::dots>
>      get_case_compare<braille::encoding::dots, Context>(Context const &)
>      {
>          return {};
>      }
> }}}
>
> namespace braille {
>      template<typename T = boost::spirit::x3::unused_type>
>      using symbols = boost::spirit::x3::symbols_parser<braille::encoding::dots, T>;
> }
>
> int main()
> {
>      braille::symbols<> syms;
>      syms.add(U"\u2800");
>      std::u32string input = U" ";
>      std::u32string::const_iterator iter = input.begin();
>      std::u32string::const_iterator const end = input.end();
>      bool const success = parse(iter, end, syms);
>      return success;
> }
>
>
Try specializing the get_case_compare_impl<> template :

  template <typename Encoding>
     case_compare<Encoding> get_case_compare_impl(unused_type const&)
     {
         return case_compare<Encoding>();
     }

     template <typename Encoding>
     no_case_compare<Encoding> get_case_compare_impl(no_case_tag const&)
     {
         return no_case_compare<Encoding>();
     }

Regards,

Thomas Bernard.

------------------------------------------------------------------------------
One dashboard for servers and applications across Physical-Virtual-Cloud
Widest out-of-the-box monitoring support with 50+ applications
Performance metrics, stats and reports that give you Actionable Insights
Deep dive visibility with transaction tracing using APM Insight.
http://ad.doubleclick.net/ddm/clk/290420510;117567292;y
_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general
Reply | Threaded
Open this post in threaded view
|

Re: Porting from qi::symbols to x3::symbols_parser

Mario Lang
Thomas Bernard <[hidden email]> writes:

> Le 21/05/2015 23:55, Mario Lang a écrit :
>> teajay <[hidden email]> writes:
>>
>>> Le 21/05/2015 15:59, Joel de Guzman a écrit :
>>>> On 5/21/15 9:26 PM, Mario Lang wrote:
>>>>> In my Qi based project, I have a custom symbols class that looks like
>>>>> this:
>>>>>
>>>>> struct tst_braillify {
>>>>>      template <typename Char>
>>>>>      Char operator()(Char ch) const {
>>>>>        return 0X2800 | get_dots_for_character(ch);
>>>>>      }
>>>>> };
>>>>>
>>>>> template <typename T = boost::spirit::unused_type>
>>>>> struct brl_symbols : boost::spirit::qi::symbols<
>>>>>        wchar_t, T, boost::spirit::qi::tst<wchar_t, T>, tst_braillify
>>>>> {};
>>>>>
>>>>> Trying to port this to X3, I notice that the Filter template parameter
>>>>> is no longer present in x3::symbols_parser (vs. qi::symbols).
>>>>>
>>>>> It now seems to be internally used to handle case comparison.
>>>>>
>>>>> Am I missing something, or is the ability to provide a custom Filter
>>>>> gone now?  What should I do to implement similar behaviour in an X3
>>>>> based parser?
>>>> I guess I tried to hard at simplification. I never thought anyone was using
>>>> that. It is not even documented:
>>>>
>>>>
>>>> http://www.boost.org/doc/libs/1_57_0/libs/spirit/doc/html/spirit/qi/reference/string/symbols.html
>>>>
>>>> OK, here's the deal: port it back and I'll use the forward port as long
>>>> as all tests pass. Deal? Oh and one more thing, you'll also have to
>>>> add the docs for this "Filter" for it once we're there :-)
>>> The filter is not completly gone. It's still there but is used only
>>> internally for case insensitive parsing, like this:
>>>
>>>       if (value_type* val_ptr
>>>         = lookup->find(first, last, get_case_compare<Encoding>(context)))
>>>
>>> from symbols.hpp.
>>>
>>> Right now the filter is fetched through the get_case_compare template
>>> according to the encoding, so maybe you could define a custom encoding
>>> and customize the get_case_compare template to return the correct filter.
>> Nice hint.  However, I think this is not possible, because:
>>
>> cc.cpp:33:71: error: non-class, non-variable partial specialization ‘get_case_compare<braille::encoding::dots, Context>’ is not allowed
>>
>> #include <boost/spirit/home/x3.hpp>
>>
>> namespace braille {
>>      namespace encoding {
>>          struct dots
>>          {
>>              using char_type = char32_t;
>>          };
>>      }
>>
>>      template <typename Encoding>
>>      struct dots_compare
>>      {
>>          int32_t operator()(
>>                typename Encoding::char_type const lc
>>              , typename Encoding::char_type const rc) const
>>          {
>>              // do magic here
>>              return lc - rc;
>>          }
>>
>>          template <typename CharClassTag>
>>          CharClassTag get_char_class_tag(CharClassTag tag) const
>>          {
>>              return tag;
>>          }
>>      };
>> }
>>
>> namespace boost { namespace spirit { namespace x3 {
>>      template <typename Context>
>>      braille::dots_compare<braille::encoding::dots>
>>      get_case_compare<braille::encoding::dots, Context>(Context const &)
>>      {
>>          return {};
>>      }
>> }}}
>>
>> namespace braille {
>>      template<typename T = boost::spirit::x3::unused_type>
>>      using symbols = boost::spirit::x3::symbols_parser<braille::encoding::dots, T>;
>> }
>>
>> int main()
>> {
>>      braille::symbols<> syms;
>>      syms.add(U"\u2800");
>>      std::u32string input = U" ";
>>      std::u32string::const_iterator iter = input.begin();
>>      std::u32string::const_iterator const end = input.end();
>>      bool const success = parse(iter, end, syms);
>>      return success;
>> }
>>
>>
> Try specializing the get_case_compare_impl<> template :
>
>   template <typename Encoding>
>      case_compare<Encoding> get_case_compare_impl(unused_type const&)
>      {
>          return case_compare<Encoding>();
>      }
>
>      template <typename Encoding>
>      no_case_compare<Encoding> get_case_compare_impl(no_case_tag const&)
>      {
>          return no_case_compare<Encoding>();
>      }

This doesn't seem to help either, I now get:

cc.cpp:33:5: error: template-id ‘get_case_compare_impl<braille::encoding::dots>’ for ‘braille::dots_compare<braille::encoding::dots> boost::spirit::x3::get_case_compare_impl(const boost::spirit::x3::unused_type&)’ does not match any template declaration

namespace boost { namespace spirit { namespace x3 {
    template <>
    braille::dots_compare<braille::encoding::dots>
    get_case_compare_impl<braille::encoding::dots>(unused_type const&)
    {
        return {};
    }
}}}

--
CYa,
  ⡍⠁⠗⠊⠕

------------------------------------------------------------------------------
One dashboard for servers and applications across Physical-Virtual-Cloud
Widest out-of-the-box monitoring support with 50+ applications
Performance metrics, stats and reports that give you Actionable Insights
Deep dive visibility with transaction tracing using APM Insight.
http://ad.doubleclick.net/ddm/clk/290420510;117567292;y
_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general
Reply | Threaded
Open this post in threaded view
|

Re: Porting from qi::symbols to x3::symbols_parser

Mario Lang
Mario Lang <[hidden email]> writes:

> Thomas Bernard <[hidden email]> writes:
>
>> Le 21/05/2015 23:55, Mario Lang a écrit :
>>> teajay <[hidden email]> writes:
>>>
>>>> Le 21/05/2015 15:59, Joel de Guzman a écrit :
>>>>> On 5/21/15 9:26 PM, Mario Lang wrote:
>>>>>> In my Qi based project, I have a custom symbols class that looks like
>>>>>> this:
>>>>>>
>>>>>> struct tst_braillify {
>>>>>>      template <typename Char>
>>>>>>      Char operator()(Char ch) const {
>>>>>>        return 0X2800 | get_dots_for_character(ch);
>>>>>>      }
>>>>>> };
>>>>>>
>>>>>> template <typename T = boost::spirit::unused_type>
>>>>>> struct brl_symbols : boost::spirit::qi::symbols<
>>>>>>        wchar_t, T, boost::spirit::qi::tst<wchar_t, T>, tst_braillify
>>>>>> {};
>>>>>>
>>>>>> Trying to port this to X3, I notice that the Filter template parameter
>>>>>> is no longer present in x3::symbols_parser (vs. qi::symbols).
>>>>>>
>>>>>> It now seems to be internally used to handle case comparison.
>>>>>>
>>>>>> Am I missing something, or is the ability to provide a custom Filter
>>>>>> gone now?  What should I do to implement similar behaviour in an X3
>>>>>> based parser?
>>>>> I guess I tried to hard at simplification. I never thought anyone was using
>>>>> that. It is not even documented:
>>>>>
>>>>>
>>>>> http://www.boost.org/doc/libs/1_57_0/libs/spirit/doc/html/spirit/qi/reference/string/symbols.html
>>>>>
>>>>> OK, here's the deal: port it back and I'll use the forward port as long
>>>>> as all tests pass. Deal? Oh and one more thing, you'll also have to
>>>>> add the docs for this "Filter" for it once we're there :-)
>>>> The filter is not completly gone. It's still there but is used only
>>>> internally for case insensitive parsing, like this:
>>>>
>>>>       if (value_type* val_ptr
>>>>         = lookup->find(first, last, get_case_compare<Encoding>(context)))
>>>>
>>>> from symbols.hpp.
>>>>
>>>> Right now the filter is fetched through the get_case_compare template
>>>> according to the encoding, so maybe you could define a custom encoding
>>>> and customize the get_case_compare template to return the correct filter.
>>> Nice hint.  However, I think this is not possible, because:
>>>
>>> cc.cpp:33:71: error: non-class, non-variable partial specialization ‘get_case_compare<braille::encoding::dots, Context>’ is not allowed
>>>
>>> #include <boost/spirit/home/x3.hpp>
>>>
>>> namespace braille {
>>>      namespace encoding {
>>>          struct dots
>>>          {
>>>              using char_type = char32_t;
>>>          };
>>>      }
>>>
>>>      template <typename Encoding>
>>>      struct dots_compare
>>>      {
>>>          int32_t operator()(
>>>                typename Encoding::char_type const lc
>>>              , typename Encoding::char_type const rc) const
>>>          {
>>>              // do magic here
>>>              return lc - rc;
>>>          }
>>>
>>>          template <typename CharClassTag>
>>>          CharClassTag get_char_class_tag(CharClassTag tag) const
>>>          {
>>>              return tag;
>>>          }
>>>      };
>>> }
>>>
>>> namespace boost { namespace spirit { namespace x3 {
>>>      template <typename Context>
>>>      braille::dots_compare<braille::encoding::dots>
>>>      get_case_compare<braille::encoding::dots, Context>(Context const &)
>>>      {
>>>          return {};
>>>      }
>>> }}}
>>>
>>> namespace braille {
>>>      template<typename T = boost::spirit::x3::unused_type>
>>>      using symbols = boost::spirit::x3::symbols_parser<braille::encoding::dots, T>;
>>> }
>>>
>>> int main()
>>> {
>>>      braille::symbols<> syms;
>>>      syms.add(U"\u2800");
>>>      std::u32string input = U" ";
>>>      std::u32string::const_iterator iter = input.begin();
>>>      std::u32string::const_iterator const end = input.end();
>>>      bool const success = parse(iter, end, syms);
>>>      return success;
>>> }
>>
>> Try specializing the get_case_compare_impl<> template :
>>
>>   template <typename Encoding>
>>      case_compare<Encoding> get_case_compare_impl(unused_type const&)
>>      {
>>          return case_compare<Encoding>();
>>      }
>>
>>      template <typename Encoding>
>>      no_case_compare<Encoding> get_case_compare_impl(no_case_tag const&)
>>      {
>>          return no_case_compare<Encoding>();
>>      }
>
> This doesn't seem to help either, I now get:
>
> cc.cpp:33:5: error: template-id ‘get_case_compare_impl<braille::encoding::dots>’ for ‘braille::dots_compare<braille::encoding::dots> boost::spirit::x3::get_case_compare_impl(const boost::spirit::x3::unused_type&)’ does not match any template declaration
>
> namespace boost { namespace spirit { namespace x3 {
>     template <>
>     braille::dots_compare<braille::encoding::dots>
>     get_case_compare_impl<braille::encoding::dots>(unused_type const&)
>     {
>         return {};
>     }
> }}}

And a version using x3::with doesn't work either.  It actually compiles,
but the custom comparator is never called.  My template fu might
be far too limited, but I don't see a way to provide custom case
comparison.

#include <boost/spirit/home/x3.hpp>

namespace braille {
    namespace encoding {
        struct dots
        {
            using char_type = char32_t;
        };
    }

    template <typename Encoding>
    struct dots_compare
    {
        int32_t operator()(
              typename Encoding::char_type const lc
            , typename Encoding::char_type const rc) const
        {
            // do magic here
            auto to_dots = [](typename Encoding::char_type c) {
                std::clog << c << std::endl;
                switch (c) {
                case ' ': return 0X2800;
                default: return c;
                }
            };
            return to_dots(lc) - to_dots(rc);
        }

        template <typename CharClassTag>
        CharClassTag get_char_class_tag(CharClassTag tag) const
        {
            return tag;
        }
    };
    struct dots_compare_tag {};
}

namespace boost { namespace spirit { namespace x3 {
    template <typename Encoding>
    braille::dots_compare<Encoding>
    get_case_compare_impl(braille::dots_compare_tag const&)
    {
        return {};
    }
}}}

namespace braille {
    template<typename T = boost::spirit::x3::unused_type>
    using symbols = boost::spirit::x3::symbols_parser<braille::encoding::dots, T>;
}

int main()
{
    using boost::spirit::x3::no_case_tag;
    using boost::spirit::x3::with;
    braille::symbols<> syms;
    syms.add(U"\u2800");
    std::u32string input = U" ";
    std::u32string::const_iterator iter = input.begin();
    std::u32string::const_iterator const end = input.end();
    bool const success = parse(iter, end,
        with<no_case_tag>(braille::dots_compare_tag{})[syms]);
    return success;
}


--
CYa,
  ⡍⠁⠗⠊⠕ | Debian Developer <URL:http://debian.org/>
  .''`. | Get my public key via finger mlang/[hidden email]
 : :' : | 1024D/7FC1A0854909BCCDBE6C102DDFFC022A6B113E44
 `. `'
   `-      <URL:http://delysid.org/>  <URL:http://www.staff.tugraz.at/mlang/>

------------------------------------------------------------------------------
One dashboard for servers and applications across Physical-Virtual-Cloud
Widest out-of-the-box monitoring support with 50+ applications
Performance metrics, stats and reports that give you Actionable Insights
Deep dive visibility with transaction tracing using APM Insight.
http://ad.doubleclick.net/ddm/clk/290420510;117567292;y
_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general
Reply | Threaded
Open this post in threaded view
|

Re: Porting from qi::symbols to x3::symbols_parser

Joel de Guzman
On 5/22/15 7:02 AM, Mario Lang wrote:

> Mario Lang <[hidden email]> writes:
>
>> Thomas Bernard <[hidden email]> writes:
>>
>>> Le 21/05/2015 23:55, Mario Lang a écrit :
>>>> teajay <[hidden email]> writes:
>>>>
>>>>> Le 21/05/2015 15:59, Joel de Guzman a écrit :
>>>>>> On 5/21/15 9:26 PM, Mario Lang wrote:
>>>>>>> In my Qi based project, I have a custom symbols class that looks like
>>>>>>> this:
>>>>>>>
>>>>>>> struct tst_braillify {
>>>>>>>       template <typename Char>
>>>>>>>       Char operator()(Char ch) const {
>>>>>>>         return 0X2800 | get_dots_for_character(ch);
>>>>>>>       }
>>>>>>> };
>>>>>>>
>>>>>>> template <typename T = boost::spirit::unused_type>
>>>>>>> struct brl_symbols : boost::spirit::qi::symbols<
>>>>>>>         wchar_t, T, boost::spirit::qi::tst<wchar_t, T>, tst_braillify
>>>>>>> {};
>>>>>>>
>>>>>>> Trying to port this to X3, I notice that the Filter template parameter
>>>>>>> is no longer present in x3::symbols_parser (vs. qi::symbols).
>>>>>>>
>>>>>>> It now seems to be internally used to handle case comparison.
>>>>>>>
>>>>>>> Am I missing something, or is the ability to provide a custom Filter
>>>>>>> gone now?  What should I do to implement similar behaviour in an X3
>>>>>>> based parser?
>>>>>> I guess I tried to hard at simplification. I never thought anyone was using
>>>>>> that. It is not even documented:
>>>>>>
>>>>>>
>>>>>> http://www.boost.org/doc/libs/1_57_0/libs/spirit/doc/html/spirit/qi/reference/string/symbols.html
>>>>>>
>>>>>> OK, here's the deal: port it back and I'll use the forward port as long
>>>>>> as all tests pass. Deal? Oh and one more thing, you'll also have to
>>>>>> add the docs for this "Filter" for it once we're there :-)
>>>>> The filter is not completly gone. It's still there but is used only
>>>>> internally for case insensitive parsing, like this:
>>>>>
>>>>>        if (value_type* val_ptr
>>>>>          = lookup->find(first, last, get_case_compare<Encoding>(context)))
>>>>>
>>>>> from symbols.hpp.
>>>>>
>>>>> Right now the filter is fetched through the get_case_compare template
>>>>> according to the encoding, so maybe you could define a custom encoding
>>>>> and customize the get_case_compare template to return the correct filter.
>>>> Nice hint.  However, I think this is not possible, because:

[Snip]

I think this mechanism should be made generic using customization points.

Regards,
--
Joel de Guzman
http://www.ciere.com
http://boost-spirit.com
http://www.cycfi.com/


------------------------------------------------------------------------------
One dashboard for servers and applications across Physical-Virtual-Cloud
Widest out-of-the-box monitoring support with 50+ applications
Performance metrics, stats and reports that give you Actionable Insights
Deep dive visibility with transaction tracing using APM Insight.
http://ad.doubleclick.net/ddm/clk/290420510;117567292;y
_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general
Reply | Threaded
Open this post in threaded view
|

Re: Porting from qi::symbols to x3::symbols_parser

teajay-2
Le 22/05/2015 05:11, Joel de Guzman a écrit :

> On 5/22/15 7:02 AM, Mario Lang wrote:
>> Mario Lang <[hidden email]> writes:
>>
>>> Thomas Bernard <[hidden email]> writes:
>>>
>>>> Le 21/05/2015 23:55, Mario Lang a écrit :
>>>>> teajay <[hidden email]> writes:
>>>>>
>>>>>> Le 21/05/2015 15:59, Joel de Guzman a écrit :
>>>>>>> On 5/21/15 9:26 PM, Mario Lang wrote:
>>>>>>>> In my Qi based project, I have a custom symbols class that looks like
>>>>>>>> this:
>>>>>>>>
>>>>>>>> struct tst_braillify {
>>>>>>>>        template <typename Char>
>>>>>>>>        Char operator()(Char ch) const {
>>>>>>>>          return 0X2800 | get_dots_for_character(ch);
>>>>>>>>        }
>>>>>>>> };
>>>>>>>>
>>>>>>>> template <typename T = boost::spirit::unused_type>
>>>>>>>> struct brl_symbols : boost::spirit::qi::symbols<
>>>>>>>>          wchar_t, T, boost::spirit::qi::tst<wchar_t, T>, tst_braillify
>>>>>>>> {};
>>>>>>>>
>>>>>>>> Trying to port this to X3, I notice that the Filter template parameter
>>>>>>>> is no longer present in x3::symbols_parser (vs. qi::symbols).
>>>>>>>>
>>>>>>>> It now seems to be internally used to handle case comparison.
>>>>>>>>
>>>>>>>> Am I missing something, or is the ability to provide a custom Filter
>>>>>>>> gone now?  What should I do to implement similar behaviour in an X3
>>>>>>>> based parser?
>>>>>>> I guess I tried to hard at simplification. I never thought anyone was using
>>>>>>> that. It is not even documented:
>>>>>>>
>>>>>>>
>>>>>>> http://www.boost.org/doc/libs/1_57_0/libs/spirit/doc/html/spirit/qi/reference/string/symbols.html
>>>>>>>
>>>>>>> OK, here's the deal: port it back and I'll use the forward port as long
>>>>>>> as all tests pass. Deal? Oh and one more thing, you'll also have to
>>>>>>> add the docs for this "Filter" for it once we're there :-)
>>>>>> The filter is not completly gone. It's still there but is used only
>>>>>> internally for case insensitive parsing, like this:
>>>>>>
>>>>>>         if (value_type* val_ptr
>>>>>>           = lookup->find(first, last, get_case_compare<Encoding>(context)))
>>>>>>
>>>>>> from symbols.hpp.
>>>>>>
>>>>>> Right now the filter is fetched through the get_case_compare template
>>>>>> according to the encoding, so maybe you could define a custom encoding
>>>>>> and customize the get_case_compare template to return the correct filter.
>>>>> Nice hint.  However, I think this is not possible, because:
> [Snip]
>
> I think this mechanism should be made generic using customization points.
>
> Regards,
I'll have a look at this over the weekend.
Should we consider this only for the symbols parser or for the case
insentive filter in all parsers ?

Regards,

Thomas Bernard

------------------------------------------------------------------------------
One dashboard for servers and applications across Physical-Virtual-Cloud
Widest out-of-the-box monitoring support with 50+ applications
Performance metrics, stats and reports that give you Actionable Insights
Deep dive visibility with transaction tracing using APM Insight.
http://ad.doubleclick.net/ddm/clk/290420510;117567292;y
_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general
Reply | Threaded
Open this post in threaded view
|

Re: Porting from qi::symbols to x3::symbols_parser

Joel de Guzman
On 5/23/15 4:16 AM, Thomas Bernard wrote:

> Le 22/05/2015 05:11, Joel de Guzman a écrit :
>> On 5/22/15 7:02 AM, Mario Lang wrote:
>>> Mario Lang <[hidden email]> writes:
>>>
>>>> Thomas Bernard <[hidden email]> writes:
>>>>
>>>>> Le 21/05/2015 23:55, Mario Lang a écrit :
>>>>>> teajay <[hidden email]> writes:
>>>>>>
>>>>>>> Le 21/05/2015 15:59, Joel de Guzman a écrit :
>>>>>>>> On 5/21/15 9:26 PM, Mario Lang wrote:
>>>>>>>>> In my Qi based project, I have a custom symbols class that looks like
>>>>>>>>> this:
>>>>>>>>>
>>>>>>>>> struct tst_braillify {
>>>>>>>>>         template <typename Char>
>>>>>>>>>         Char operator()(Char ch) const {
>>>>>>>>>           return 0X2800 | get_dots_for_character(ch);
>>>>>>>>>         }
>>>>>>>>> };
>>>>>>>>>
>>>>>>>>> template <typename T = boost::spirit::unused_type>
>>>>>>>>> struct brl_symbols : boost::spirit::qi::symbols<
>>>>>>>>>           wchar_t, T, boost::spirit::qi::tst<wchar_t, T>, tst_braillify
>>>>>>>>> {};
>>>>>>>>>
>>>>>>>>> Trying to port this to X3, I notice that the Filter template parameter
>>>>>>>>> is no longer present in x3::symbols_parser (vs. qi::symbols).
>>>>>>>>>
>>>>>>>>> It now seems to be internally used to handle case comparison.
>>>>>>>>>
>>>>>>>>> Am I missing something, or is the ability to provide a custom Filter
>>>>>>>>> gone now?  What should I do to implement similar behaviour in an X3
>>>>>>>>> based parser?
>>>>>>>> I guess I tried to hard at simplification. I never thought anyone was using
>>>>>>>> that. It is not even documented:
>>>>>>>>
>>>>>>>>
>>>>>>>> http://www.boost.org/doc/libs/1_57_0/libs/spirit/doc/html/spirit/qi/reference/string/symbols.html
>>>>>>>>
>>>>>>>> OK, here's the deal: port it back and I'll use the forward port as long
>>>>>>>> as all tests pass. Deal? Oh and one more thing, you'll also have to
>>>>>>>> add the docs for this "Filter" for it once we're there :-)
>>>>>>> The filter is not completly gone. It's still there but is used only
>>>>>>> internally for case insensitive parsing, like this:
>>>>>>>
>>>>>>>          if (value_type* val_ptr
>>>>>>>            = lookup->find(first, last, get_case_compare<Encoding>(context)))
>>>>>>>
>>>>>>> from symbols.hpp.
>>>>>>>
>>>>>>> Right now the filter is fetched through the get_case_compare template
>>>>>>> according to the encoding, so maybe you could define a custom encoding
>>>>>>> and customize the get_case_compare template to retur BUt if you see a generic costun the correct filter.
>>>>>> Nice hint.  However, I think this is not possible, because:
>> [Snip]
>>
>> I think this mechanism should be made generic using customization points.
>>
>> Regards,
> I'll have a look at this over the weekend.
> Should we consider this only for the symbols parser or for the case
> insentive filter in all parsers ?

Whatever you do, keep it as simple as possible. I'd say limit it to just
the symbols parser, if that makes sense. But if you see a generic
customization point in the making, let's talk about it.

Regards,
--
Joel de Guzman
http://www.ciere.com
http://boost-spirit.com
http://www.cycfi.com/


------------------------------------------------------------------------------
One dashboard for servers and applications across Physical-Virtual-Cloud
Widest out-of-the-box monitoring support with 50+ applications
Performance metrics, stats and reports that give you Actionable Insights
Deep dive visibility with transaction tracing using APM Insight.
http://ad.doubleclick.net/ddm/clk/290420510;117567292;y
_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general
Reply | Threaded
Open this post in threaded view
|

Re: Porting from qi::symbols to x3::symbols_parser

teajay-2
Le 23/05/2015 02:41, Joel de Guzman a écrit :

> On 5/23/15 4:16 AM, Thomas Bernard wrote:
>> Le 22/05/2015 05:11, Joel de Guzman a écrit :
>>> On 5/22/15 7:02 AM, Mario Lang wrote:
>>>> Mario Lang <[hidden email]> writes:
>>>>
>>>>> Thomas Bernard <[hidden email]> writes:
>>>>>
>>>>>> Le 21/05/2015 23:55, Mario Lang a écrit :
>>>>>>> teajay <[hidden email]> writes:
>>>>>>>
>>>>>>>> Le 21/05/2015 15:59, Joel de Guzman a écrit :
>>>>>>>>> On 5/21/15 9:26 PM, Mario Lang wrote:
>>>>>>>>>> In my Qi based project, I have a custom symbols
>>>>>>>>>> class that looks like this:
>>>>>>>>>>
>>>>>>>>>> struct tst_braillify { template <typename Char>
>>>>>>>>>> Char operator()(Char ch) const { return 0X2800 |
>>>>>>>>>> get_dots_for_character(ch); } };
>>>>>>>>>>
>>>>>>>>>> template <typename T = boost::spirit::unused_type>
>>>>>>>>>> struct brl_symbols : boost::spirit::qi::symbols<
>>>>>>>>>> wchar_t, T, boost::spirit::qi::tst<wchar_t, T>,
>>>>>>>>>> tst_braillify {};
>>>>>>>>>>
>>>>>>>>>> Trying to port this to X3, I notice that the Filter
>>>>>>>>>> template parameter is no longer present in
>>>>>>>>>> x3::symbols_parser (vs. qi::symbols).
>>>>>>>>>>
>>>>>>>>>> It now seems to be internally used to handle case
>>>>>>>>>> comparison.
>>>>>>>>>>
>>>>>>>>>> Am I missing something, or is the ability to
>>>>>>>>>> provide a custom Filter gone now?  What should I do
>>>>>>>>>> to implement similar behaviour in an X3 based
>>>>>>>>>> parser?
>>>>>>>>> I guess I tried to hard at simplification. I never
>>>>>>>>> thought anyone was using that. It is not even
>>>>>>>>> documented:
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> http://www.boost.org/doc/libs/1_57_0/libs/spirit/doc/html/spirit/qi/reference/string/symbols.html
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
OK, here's the deal: port it back and I'll use the forward port as long

>>>>>>>>> as all tests pass. Deal? Oh and one more thing,
>>>>>>>>> you'll also have to add the docs for this "Filter"
>>>>>>>>> for it once we're there :-)
>>>>>>>> The filter is not completly gone. It's still there but
>>>>>>>> is used only internally for case insensitive parsing,
>>>>>>>> like this:
>>>>>>>>
>>>>>>>> if (value_type* val_ptr = lookup->find(first, last,
>>>>>>>> get_case_compare<Encoding>(context)))
>>>>>>>>
>>>>>>>> from symbols.hpp.
>>>>>>>>
>>>>>>>> Right now the filter is fetched through the
>>>>>>>> get_case_compare template according to the encoding, so
>>>>>>>> maybe you could define a custom encoding and customize
>>>>>>>> the get_case_compare template to retur BUt if you see a
>>>>>>>> generic costun the correct filter.
>>>>>>> Nice hint.  However, I think this is not possible,
>>>>>>> because:
>>> [Snip]
>>>
>>> I think this mechanism should be made generic using customization
>>> points.
>>>
>>> Regards,
>> I'll have a look at this over the weekend. Should we consider this
>> only for the symbols parser or for the case insentive filter in all
>> parsers ?
>
> Whatever you do, keep it as simple as possible. I'd say limit it to
> just the symbols parser, if that makes sense. But if you see a
> generic customization point in the making, let's talk about it.
>
> Regards,
>
I got the customization point added to the symbols parser. You'll find
it here until it's merged in develop:

https://github.com/teajay-fr/spirit.git
in the branch feature/x3_symbol_filter_customization.

I simply added a template parameter to the symbols parser which enables
changing the filter selection call. Usage is as follows:

   namespace braille {
       namespace encoding {
           struct dots
           {
               using char_type = char32_t;
           };
       }

       template <typename Encoding>
       struct dots_compare
       {
           int32_t operator()(
                 typename Encoding::char_type const lc
               , typename Encoding::char_type const rc) const
           {
               // do magic here
               return lc - rc;
           }

       };

       struct get_dots_compare
       {
           template <typename Context>
            static dots_compare<encoding::dots> get(Context const& context)
            {
                return {};
            }
       };
  }

  namespace braille {
       template<typename T = boost::spirit::x3::unused_type>
       using symbols =
boost::spirit::x3::symbols_parser<braille::encoding::dots, T,
get_dots_compare>;
  }

Hope this works for you.

Regards,

Thomas Bernard


------------------------------------------------------------------------------
_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general
Reply | Threaded
Open this post in threaded view
|

Re: Porting from qi::symbols to x3::symbols_parser

Mario Lang
teajay <[hidden email]> writes:

> Le 23/05/2015 02:41, Joel de Guzman a écrit :
>> On 5/23/15 4:16 AM, Thomas Bernard wrote:
>>> Le 22/05/2015 05:11, Joel de Guzman a écrit :
>>>> On 5/22/15 7:02 AM, Mario Lang wrote:
>>>>> Mario Lang <[hidden email]> writes:
>>>>>
>>>>>> Thomas Bernard <[hidden email]> writes:
>>>>>>
>>>>>>> Le 21/05/2015 23:55, Mario Lang a écrit :
>>>>>>>> teajay <[hidden email]> writes:
>>>>>>>>
>>>>>>>>> Le 21/05/2015 15:59, Joel de Guzman a écrit :
>>>>>>>>>> On 5/21/15 9:26 PM, Mario Lang wrote:
>>>>>>>>>>> In my Qi based project, I have a custom symbols
>>>>>>>>>>> class that looks like this:
>>>>>>>>>>>
>>>>>>>>>>> struct tst_braillify { template <typename Char>
>>>>>>>>>>> Char operator()(Char ch) const { return 0X2800 |
>>>>>>>>>>> get_dots_for_character(ch); } };
>>>>>>>>>>>
>>>>>>>>>>> template <typename T = boost::spirit::unused_type>
>>>>>>>>>>> struct brl_symbols : boost::spirit::qi::symbols<
>>>>>>>>>>> wchar_t, T, boost::spirit::qi::tst<wchar_t, T>,
>>>>>>>>>>> tst_braillify {};
>>>>>>>>>>>
>>>>>>>>>>> Trying to port this to X3, I notice that the Filter
>>>>>>>>>>> template parameter is no longer present in
>>>>>>>>>>> x3::symbols_parser (vs. qi::symbols).
>>>>>>>>>>>
>>>>>>>>>>> It now seems to be internally used to handle case
>>>>>>>>>>> comparison.
>>>>>>>>>>>
>>>>>>>>>>> Am I missing something, or is the ability to
>>>>>>>>>>> provide a custom Filter gone now?  What should I do
>>>>>>>>>>> to implement similar behaviour in an X3 based
>>>>>>>>>>> parser?
>>>>>>>>>> I guess I tried to hard at simplification. I never
>>>>>>>>>> thought anyone was using that. It is not even
>>>>>>>>>> documented:
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> http://www.boost.org/doc/libs/1_57_0/libs/spirit/doc/html/spirit/qi/reference/string/symbols.html
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
> OK, here's the deal: port it back and I'll use the forward port as long
>>>>>>>>>> as all tests pass. Deal? Oh and one more thing,
>>>>>>>>>> you'll also have to add the docs for this "Filter"
>>>>>>>>>> for it once we're there :-)
>>>>>>>>> The filter is not completly gone. It's still there but
>>>>>>>>> is used only internally for case insensitive parsing,
>>>>>>>>> like this:
>>>>>>>>>
>>>>>>>>> if (value_type* val_ptr = lookup->find(first, last,
>>>>>>>>> get_case_compare<Encoding>(context)))
>>>>>>>>>
>>>>>>>>> from symbols.hpp.
>>>>>>>>>
>>>>>>>>> Right now the filter is fetched through the
>>>>>>>>> get_case_compare template according to the encoding, so
>>>>>>>>> maybe you could define a custom encoding and customize
>>>>>>>>> the get_case_compare template to retur BUt if you see a
>>>>>>>>> generic costun the correct filter.
>>>>>>>> Nice hint.  However, I think this is not possible,
>>>>>>>> because:
>>>> [Snip]
>>>>
>>>> I think this mechanism should be made generic using customization
>>>> points.
>>>>
>>>> Regards,
>>> I'll have a look at this over the weekend. Should we consider this
>>> only for the symbols parser or for the case insentive filter in all
>>> parsers ?
>>
>> Whatever you do, keep it as simple as possible. I'd say limit it to
>> just the symbols parser, if that makes sense. But if you see a
>> generic customization point in the making, let's talk about it.
>>
>> Regards,
>>
> I got the customization point added to the symbols parser. You'll find
> it here until it's merged in develop:
>
> https://github.com/teajay-fr/spirit.git
> in the branch feature/x3_symbol_filter_customization.
>
> I simply added a template parameter to the symbols parser which enables
> changing the filter selection call. Usage is as follows:
>
>    namespace braille {
>        namespace encoding {
>            struct dots
>            {
>                using char_type = char32_t;
>            };
>        }
>
>        template <typename Encoding>
>        struct dots_compare
>        {
>            int32_t operator()(
>                  typename Encoding::char_type const lc
>                , typename Encoding::char_type const rc) const
>            {
>                // do magic here
>                return lc - rc;
>            }
>
>        };
>
>        struct get_dots_compare
>        {
>            template <typename Context>
>             static dots_compare<encoding::dots> get(Context const& context)
>             {
>                 return {};
>             }
>        };
>   }
>
>   namespace braille {
>        template<typename T = boost::spirit::x3::unused_type>
>        using symbols =
> boost::spirit::x3::symbols_parser<braille::encoding::dots, T,
> get_dots_compare>;
>   }
>
> Hope this works for you.

Thanks!  I have switched a few symbol tables to plain alternative
parsers with attr() on the rhs by now, since they were only looking at
*one* character, IOW, the symbols template would not have provided any
speedup anyways.  However, I have some symbol tables with more than one
character left, so this will be very useful.  Thanks again.

--
CYa,
  ⡍⠁⠗⠊⠕

------------------------------------------------------------------------------
_______________________________________________
Spirit-general mailing list
[hidden email]
https://lists.sourceforge.net/lists/listinfo/spirit-general