#! /usr/bin/env python
# -*- coding: utf-8 -*-

import vcsn
from test import *
from vcsn_tools.demangle import demangle, sugar

try:
    import regex
    has_regex = True
except ImportError:
    has_regex = False


## ---------- ##
## demangle.  ##
## ---------- ##

def check(input, exp_regex, exp_re=None):
    '''Check that `demangle(input)` is `exp1` when regex is available,
    otherwise `exp2`.'''
    if exp_re is None:
        exp_re = input
    exp = exp_regex if has_regex else exp_re
    CHECK_EQ(exp, demangle(input, color="never"))

check('nullableset<vcsn::weightset_mixin<vcsn::detail::tupleset_impl<lal_char, vcsn::weightset_mixin<vcsn::detail::tupleset_impl<vcsn::nullableset<lal_char >, law_char > > > > >',
      'nullableset<tupleset<lal_char, tupleset<nullableset<lal_char >, law_char > > >')

check('index_t_impl<vcsn::detail::mutable_automaton_impl<vcsn::context<vcsn::letterset<vcsn::set_alphabet<vcsn::char_letters> >, vcsn::weightset_mixin<vcsn::detail::b_impl> > >::state_tag>',
      'vcsn::detail::mutable_automaton_impl<context<lal_char, b > >::state_t',
      'index_t_impl<vcsn::detail::mutable_automaton_impl<vcsn::context<lal_char, b > >::state_tag>')

check('''
vcsn/algos/pair.hh:229:21: error: no viable conversion from 'index_t_impl<vcsn::detail::mutable_automaton_impl<vcsn::context<vcsn::letterset<vcsn::set_alphabet<vcsn::char_letters> >, vcsn::weightset_mixin<vcsn::detail::b_impl> > >::state_tag>' to 'index_t_impl<vcsn::detail::mutable_automaton_impl<vcsn::context<vcsn::weightset_mixin<vcsn::detail::tupleset_impl<vcsn::letterset<vcsn::set_alphabet<vcsn::char_letters> >, vcsn::letterset<vcsn::set_alphabet<vcsn::char_letters> >, vcsn::letterset<vcsn::set_alphabet<vcsn::char_letters> > > >, vcsn::weightset_mixin<vcsn::detail::b_impl> > >::state_tag>'
      state_t q0_ = this->null_state();
                    ^~~~~~~~~~~~~~~~~~
''',
      '''
vcsn/algos/pair.hh:229:21: error: no viable conversion from 'vcsn::detail::mutable_automaton_impl<context<lal_char, b > >::state_t' to 'vcsn::detail::mutable_automaton_impl<context<tupleset<lal_char, lal_char, lal_char >, b > >::state_t'
      state_t q0_ = this->null_state();
                    ^~~~~~~~~~~~~~~~~~
''',
      '''
vcsn/algos/pair.hh:229:21: error: no viable conversion from 'index_t_impl<vcsn::detail::mutable_automaton_impl<vcsn::context<lal_char, b > >::state_tag>' to 'index_t_impl<vcsn::detail::mutable_automaton_impl<vcsn::context<vcsn::weightset_mixin<vcsn::detail::tupleset_impl<lal_char, lal_char, lal_char > >, b > >::state_tag>'
      state_t q0_ = this->null_state();
                    ^~~~~~~~~~~~~~~~~~
''')

check('''
vcsn/misc/pair.hh:36:12: error: no viable conversion from 'pair<typename __make_pair_return<index_t_impl<state_tag> &>::type, typename __make_pair_return<index_t_impl<state_tag> &>::type>' to 'pair<vcsn::detail::index_t_impl<vcsn::detail::mutable_automaton_impl<vcsn::context<vcsn::weightset_mixin<vcsn::detail::tupleset_impl<vcsn::letterset<vcsn::set_alphabet<vcsn::char_letters> >, vcsn::letterset<vcsn::set_alphabet<vcsn::char_letters> >, vcsn::letterset<vcsn::set_alphabet<vcsn::char_letters> > > >, vcsn::weightset_mixin<vcsn::detail::b_impl> > >::state_tag> &, vcsn::detail::index_t_impl<vcsn::detail::mutable_automaton_impl<vcsn::context<vcsn::weightset_mixin<vcsn::detail::tupleset_impl<vcsn::letterset<vcsn::set_alphabet<vcsn::char_letters> >, vcsn::letterset<vcsn::set_alphabet<vcsn::char_letters> >, vcsn::letterset<vcsn::set_alphabet<vcsn::char_letters> > > >, vcsn::weightset_mixin<vcsn::detail::b_impl> > >::state_tag> &>'
''',
      '''
vcsn/misc/pair.hh:36:12: error: no viable conversion from 'pair<typename __make_pair_return<index_t_impl<state_tag> &>::type, typename __make_pair_return<index_t_impl<state_tag> &>::type>' to 'pair<vcsn::detail::mutable_automaton_impl<context<tupleset<lal_char, lal_char, lal_char >, b > >::state_t &, vcsn::detail::mutable_automaton_impl<context<tupleset<lal_char, lal_char, lal_char >, b > >::state_t &>'
''',
      '''
vcsn/misc/pair.hh:36:12: error: no viable conversion from 'pair<typename __make_pair_return<index_t_impl<state_tag> &>::type, typename __make_pair_return<index_t_impl<state_tag> &>::type>' to 'pair<vcsn::detail::index_t_impl<vcsn::detail::mutable_automaton_impl<vcsn::context<vcsn::weightset_mixin<vcsn::detail::tupleset_impl<lal_char, lal_char, lal_char > >, b > >::state_tag> &, vcsn::detail::index_t_impl<vcsn::detail::mutable_automaton_impl<vcsn::context<vcsn::weightset_mixin<vcsn::detail::tupleset_impl<lal_char, lal_char, lal_char > >, b > >::state_tag> &>'
''')

# From address sanitizer.
check('''
#1 0x10f6376f8 in void std::__1::vector<vcsn::detail::index_t_impl<vcsn::detail::mutable_automaton_impl<vcsn::context<vcsn::letterset<vcsn::set_alphabet<vcsn::char_letters> >, vcsn::weightset_mixin<vcsn::detail::b_impl> > >::transition_tag>, std::__1::allocator<vcsn::detail::index_t_impl<vcsn::detail::mutable_automaton_impl<vcsn::context<vcsn::letterset<vcsn::set_alphabet<vcsn::char_letters> >, vcsn::weightset_mixin<vcsn::detail::b_impl> > >::transition_tag> > >::__emplace_back_slow_path<vcsn::detail::index_t_impl<vcsn::detail::mutable_automaton_impl<vcsn::context<vcsn::letterset<vcsn::set_alphabet<vcsn::char_letters> >, vcsn::weightset_mixin<vcsn::detail::b_impl> > >::transition_tag>&>(vcsn::detail::index_t_impl<vcsn::detail::mutable_automaton_impl<vcsn::context<vcsn::letterset<vcsn::set_alphabet<vcsn::char_letters> >, vcsn::weightset_mixin<vcsn::detail::b_impl> > >::transition_tag>&&&) (/Users/akim/src/lrde/2/_build/37d/lib/plugins/algos/strip/filter_automaton<mutable_automaton<context<letterset<char_letters>, b>>>.so+0x9d6f8)
''',
      '''
#1 0x10f6376f8 in void std::vector<vcsn::detail::mutable_automaton_impl<context<lal_char, b > >::transition_t>::__emplace_back_slow_path<vcsn::detail::mutable_automaton_impl<context<lal_char, b > >::transition_t&>(vcsn::detail::mutable_automaton_impl<context<lal_char, b > >::transition_t&&&) (/Users/akim/src/lrde/2/_build/37d/lib/plugins/algos/strip/filter_automaton<mutable_automaton<context<letterset<char_letters>, b>>>.so+0x9d6f8)
''',
      '''
#1 0x10f6376f8 in void std::vector<vcsn::detail::index_t_impl<vcsn::detail::mutable_automaton_impl<vcsn::context<lal_char, b > >::transition_tag>, std::allocator<vcsn::detail::index_t_impl<vcsn::detail::mutable_automaton_impl<vcsn::context<lal_char, b > >::transition_tag> > >::__emplace_back_slow_path<vcsn::detail::index_t_impl<vcsn::detail::mutable_automaton_impl<vcsn::context<lal_char, b > >::transition_tag>&>(vcsn::detail::index_t_impl<vcsn::detail::mutable_automaton_impl<vcsn::context<lal_char, b > >::transition_tag>&&&) (/Users/akim/src/lrde/2/_build/37d/lib/plugins/algos/strip/filter_automaton<mutable_automaton<context<letterset<char_letters>, b>>>.so+0x9d6f8)
''')

# From address sanitizer.  The message is so long that its end is missing!
check('''
#4 0x10f60846d in void vcsn::detail::copier<std::__1::shared_ptr<vcsn::detail::mutable_automaton_impl<vcsn::context<vcsn::letterset<vcsn::set_alphabet<vcsn::char_letters> >, vcsn::weightset_mixin<vcsn::detail::b_impl> > > >, std::__1::shared_ptr<vcsn::detail::mutable_automaton_impl<vcsn::context<vcsn::letterset<vcsn::set_alphabet<vcsn::char_letters> >, vcsn::weightset_mixin<vcsn::detail::b_impl> > > > >::operator()<decltype((has(fp0fp->null_state())) , (make_fresh_automaton<std::__1::shared_ptr<vcsn::detail::mutable_automaton_impl<vcsn::context<vcsn::letterset<vcsn::set_alphabet<vcsn::char_letters> >, vcsn::weightset_mixin<vcsn::detail::b_impl> > > >, std::__1::shared_ptr<vcsn::detail::mutable_automaton_impl<vcsn::context<vcsn::letterset<vcsn::set_alphabet<vcsn::char_letters> >, vcsn::weightset_mixin<vcsn::detail::b_impl> > > > >(fp))) vcsn::copy<std::__1::shared_ptr<vcsn::detail::mutable_automaton_impl<vcsn::context<vcsn::letterset<vcsn::set_alphabet<vcsn::char_letters> >, vcsn::weightset_mixin<vcsn::detail::b_impl> > > >, std::__1::shared_ptr<vcsn::detail::mutable_automaton_impl<vcsn::context<vcsn::letterset<vcsn::set_alphabet<vcsn::char_letters> >, vcsn::weightset_mixin<vcsn::detail::b_impl> > > >, std::__1::unordered_set<vcsn::detail::index_t_impl<vcsn::detail::mutable_automaton_impl<vcsn::context<vcsn::letterset<vcsn::set_alphabet<vcsn::char_letters> >, vcsn::weightset_mixin<vcsn::detail::b_impl> > >::state_tag>, std::__1::hash<vcsn::detail::index_t_impl<vcsn::detail::mutable_automaton_impl<vcsn::context<vcsn::letterset<vcsn::set_alphabet<vcsn::char_letters> >, vcsn::weightset_mixin<vcsn::detail::b_impl> > >::state_tag> >, std::__1::equal_to<vcsn::detail::index_t_impl<vcsn::detail::mutable_automaton_impl<vcsn::context<vcsn::letterset<vcsn::set_alphabet<vcsn::char_letters> >, vcsn::weightset_mixin<vcsn::detail::b_impl> > >::state_tag> >, std::__1::allocator<vcsn::detail::index_t_impl<vcsn::detail::mutable_automaton_impl<vcsn::context<vcsn::letterset<vcsn::set_alphabet<vcsn::char_letters> >, vcsn::weightset_mixin<vcsn::detail::b_impl> > >::state_tag> > > >(std::__1::shared_ptr<vcsn::detail::mutable_automaton_impl<vcsn::context<vcsn::letterset<vcsn::set_alphabet<vcsn::char_letters> >, vcsn::weightset_mixin<vcsn::detail::b_impl> > > > const&, std::__1::unordered_set<vcsn::detail::index_t_impl<vcsn::detail::mutable_automaton_impl<vcsn::context<vcsn::letterset<vcsn::set_alphabet<vcsn::char_letters> >, vcsn::weightset_mixin<vcsn::detail::b_impl> > >::state_tag>, std::__1::hash<vcsn::detail::index_t_impl<vcsn::detail::mutable_automaton_impl<vcsn::context<vcsn::letterset<vcsn::set_alphabet<vcsn::char_letters> >, vcsn::weightset_mixin<vcsn::detail::b_impl> > >::state_tag> >, std::__1::equal_to<vcsn::detail::index_t_impl<vcsn::detail::mutable_automaton_impl<vcsn::context<vcsn::letterset<vcsn::set_alphabet<vcsn::char_letters> >, vcsn::weightset_mixin<vcsn::detail::b_impl> > >::state_tag> >, std::__1::allocator<vcsn::detail::index_t_impl<vcsn::detail::mutable_automaton_impl<vcsn::context<vcsn::letterset<vcsn::set_alphabet<vcsn::char_letters> >, vcsn::weightset_mixin<vcsn::detail::b_impl> > >::state_tag> > >)::'lambda'(vcsn::detail::index_t_impl<vcsn::detail::mutable_automaton_impl<vcsn::context<vcsn::letterset<vcsn::set_alphabet<vcsn::char_letters> >, vcsn::weightset_mixin<vcsn::detail::b_impl> > >::state_tag>), decltype((fp0(fp->null_state())) , (make_fresh_automaton<std::__1::shared_ptr<vcsn::detail::mutable_automaton_impl<vcsn::context<vcsn::letterset<vcsn::set_alphabet<vcsn::char_letters> >, vcsn::weightset_mixin<vcsn::detail::b_impl> > > >, std::__1::shared_ptr<vcsn::detail::mutable_automaton_impl<vcsn::context<vcsn::letterset<vcsn::set_alphabet<vcsn::char_letters> >, vcsn::weightset_mixin<vcsn::detail::b_impl> > > > >(fp))) vcsn::copy<std::__1::shared_ptr<vcsn::detail::mutable_automaton_impl<vcsn::context<vcsn::letterset<vcsn::set_alphabet<vcsn::char_letters> >, vcsn::weightset_mixin<vcsn::detail::b_impl> > > >, std::__1::shared_ptr<vcsn::detail::mutable_automaton_impl<vcsn::context<vcsn::letterset<vcsn::set_alphabet<vcsn::char_letters> >, vcsn::weightset_mixin<vcsn::detail::b_impl> > > >, decltype((has(fp0fp->null_state())) , (make_fresh_automaton<std::__1::shared_ptr<vcsn::detail::mutable_automaton_impl<vcsn::context<vcsn::letterset<vcsn::set_alphabet<vcsn::char_letters> >, vcsn::weightset_mixin<vcsn::detail::b_impl> > > >, std::__1::shared_ptr<vcsn::detail::mutable_automaton_impl<vcsn::context<vcsn::letterset<vcsn::set_alphabet<vcsn::char_letters> >, vcsn::weightset_mixin<vcsn::detail::b_impl> > > > >(fp))) vcsn::copy<std::__1::shared_ptr<vcsn::detail::mutable_automaton_impl<vcsn::context<vcsn::letterset<vcsn::set_alphabet<vcsn::char_letters> >, vcsn::weightset_mixin<vcsn::detail::b_impl> > > >, std::__1::shared_ptr<vcsn::detail::mutable_automaton_impl<vcsn::context<vcsn::letterset<vcsn::set_alphabet<vcsn::char_letters> >, vcsn::weightset_mixin<vcsn::detail::b_impl> > > >, std::__1::unordered_set<vcsn::detail::index_t_impl<vcsn::detail::mutable_automaton_impl<vcsn::context<vcsn::letterset<vcsn::set_alphabet<vcsn::char_letters> >, vcsn::weightset_mixin<vcsn::detail::b_impl> > >::state_tag>, std::__1::hash<vcsn::detail::index_t_impl<vcsn::detail::mutable_automaton_impl<vcsn::context<vcsn::letterset<vcsn::set_alphabet<vcsn::char_letters> >, vcsn::weightset_mixin<vcsn::detail::b_impl> > >::state_tag> >, std::__1::equal_to<vcsn::detail::index_t_impl<vcsn::detail::mutable_automaton_impl<vcsn::context<vcsn::letterset<vcsn::set_alphabet<vcsn::char_letters> >, vcsn::weightset_mixin<vcsn::detail::b_impl> > >::state_tag> >, std::__1::allocator<vcsn::detail::index_t_impl<vcsn::detail::mutable_automaton_impl<vcsn::context<vcsn::letterset<vcsn::set_alphabet<vcsn::char_letters> >, vcsn::weightset_mixin<vcsn::detail::b_impl> > >::state_tag> > > >(std::__1::shared_ptr<vcsn::detail::mutable_automaton_impl<vcsn::context<vcsn::letterset<vcsn::set_alphabet<vcsn::char_letters> >, vcsn::weightset_mixin<vcsn::detail::b_impl> > > > const&, std::__1::unordered_set<vcsn::detail::index_t_impl<vcsn::detail::mutable_automaton_impl<vcsn::context<vcsn::letterset<vcsn::set_alphabet<vcsn::char_letters> >, vcsn::weightset_mixin<vcsn::detail::b_impl> > >::state_tag>, std::__1::hash<vcsn::detail::index_t_impl<vcsn::detail::mutable_automaton_impl<vcsn::context<vcsn::letterset<vcsn::set_alphabet<vcsn::char_letters> >, vcsn::weightset_mixin<vcsn::detail::b_impl> > >::state_tag> >, std::__1::equal_to<vcsn::detail::index_t_impl<vcsn::detail::mutable_automaton_impl<vcsn::context<vcsn::letterset<vcsn::set_alphabet<vcsn::char_letters> >, vcsn::weightset_mixin<vcsn::detail::b_impl> > >::state_tag> >, std::__1::allocator<vcsn::detail::index_t_impl<vcsn::detail::mutable_automaton_impl<vcsn::context<vcsn::letterset<vcsn::set_alphabet<vcsn::char_letters> >, vcsn::weightset_mixin<vcsn::detail::b_impl> > >::state_tag> > >)::'lambda'(vcsn::detail::index_t_impl<vcsn::detail::mutable_automaton_impl<vcsn::context<vcsn::letterset<vcsn::set_alphabet<vcsn::char_letters> >, vcsn::weightset_mixin<vcsn::detail::b_impl> > >::state_tag>)>(std::__1::shared_ptr<vcsn::detail::mutable_automaton_impl<vcsn::context<vcsn::letterset<vcsn::set_alphabet<vcsn::char_letters> >, vcsn::weightset_mixin<vcsn::detail::b_impl> > > > const&, std::__1::unordered_set<vcsn::detail::index_t_impl<vcsn::detail::mutable_automaton_impl<vcsn::context<vcsn::letterset<vcsn::set_alphabet<vcsn::char_letters> >, vcsn::weightset_mixin<vcsn::detail::b_impl> > >::state_tag>, std::__1::hash<vcsn::detail::index_t_impl<vcsn::detail::mutable_automaton_impl<vcsn::context<vcsn::letterset<vcsn::set_alphabet<vcsn::char_letters> >, vcsn::weightset_mixin<vcsn::detail::b_impl> > >::state_tag> >, std::__1::equal_to<vcsn::detail::index_t_impl<vcsn::detail::mutable_automaton_impl<vcsn::context<vcsn::letterset<vcsn::set_alphabet<vcsn::char_letters> >, vcsn::weightset_mixin<vcsn::detail::b_impl> > >::state_tag> >, std::__1::allocator<vcsn::detail::index_t_impl<vcsn::detail::mutable_automaton_impl<vcsn::context<vcsn::letterset<vcsn::set_alphabet<vcsn::char_letters> >, vcsn::weightset_mixin<vcsn::detail::b_impl> > >::state_tag> > >)::'lambda'(vcs
''',
      '''
#4 0x10f60846d in void vcsn::detail::copier<mutable_automaton<context<lal_char, b > >, mutable_automaton<context<lal_char, b > > >::operator()<decltype((has(fp0fp->null_state())) , (make_fresh_automaton<mutable_automaton<context<lal_char, b > >, mutable_automaton<context<lal_char, b > > >(fp))) vcsn::copy<mutable_automaton<context<lal_char, b > >, mutable_automaton<context<lal_char, b > >, std::unordered_set<vcsn::detail::mutable_automaton_impl<context<lal_char, b > >::state_t> > >(mutable_automaton<context<lal_char, b > > const&, std::unordered_set<vcsn::detail::mutable_automaton_impl<context<lal_char, b > >::state_t> >)::'lambda'(vcsn::detail::mutable_automaton_impl<context<lal_char, b > >::state_t), decltype((fp0(fp->null_state())) , (make_fresh_automaton<mutable_automaton<context<lal_char, b > >, mutable_automaton<context<lal_char, b > > >(fp))) vcsn::copy<mutable_automaton<context<lal_char, b > >, mutable_automaton<context<lal_char, b > >, decltype((has(fp0fp->null_state())) , (make_fresh_automaton<mutable_automaton<context<lal_char, b > >, mutable_automaton<context<lal_char, b > > >(fp))) vcsn::copy<mutable_automaton<context<lal_char, b > >, mutable_automaton<context<lal_char, b > >, std::unordered_set<vcsn::detail::mutable_automaton_impl<context<lal_char, b > >::state_t> > >(mutable_automaton<context<lal_char, b > > const&, std::unordered_set<vcsn::detail::mutable_automaton_impl<context<lal_char, b > >::state_t> >)::'lambda'(vcsn::detail::mutable_automaton_impl<context<lal_char, b > >::state_t)>(mutable_automaton<context<lal_char, b > > const&, std::unordered_set<vcsn::detail::mutable_automaton_impl<context<lal_char, b > >::state_t> >)::'lambda'(vcs
''',
      '''
#4 0x10f60846d in void vcsn::detail::copier<std::shared_ptr<vcsn::detail::mutable_automaton_impl<vcsn::context<lal_char, b > > >, std::shared_ptr<vcsn::detail::mutable_automaton_impl<vcsn::context<lal_char, b > > > >::operator()<decltype((has(fp0fp->null_state())) , (make_fresh_automaton<std::shared_ptr<vcsn::detail::mutable_automaton_impl<vcsn::context<lal_char, b > > >, std::shared_ptr<vcsn::detail::mutable_automaton_impl<vcsn::context<lal_char, b > > > >(fp))) vcsn::copy<std::shared_ptr<vcsn::detail::mutable_automaton_impl<vcsn::context<lal_char, b > > >, std::shared_ptr<vcsn::detail::mutable_automaton_impl<vcsn::context<lal_char, b > > >, std::unordered_set<vcsn::detail::index_t_impl<vcsn::detail::mutable_automaton_impl<vcsn::context<lal_char, b > >::state_tag>, std::hash<vcsn::detail::index_t_impl<vcsn::detail::mutable_automaton_impl<vcsn::context<lal_char, b > >::state_tag> >, std::equal_to<vcsn::detail::index_t_impl<vcsn::detail::mutable_automaton_impl<vcsn::context<lal_char, b > >::state_tag> >, std::allocator<vcsn::detail::index_t_impl<vcsn::detail::mutable_automaton_impl<vcsn::context<lal_char, b > >::state_tag> > > >(std::shared_ptr<vcsn::detail::mutable_automaton_impl<vcsn::context<lal_char, b > > > const&, std::unordered_set<vcsn::detail::index_t_impl<vcsn::detail::mutable_automaton_impl<vcsn::context<lal_char, b > >::state_tag>, std::hash<vcsn::detail::index_t_impl<vcsn::detail::mutable_automaton_impl<vcsn::context<lal_char, b > >::state_tag> >, std::equal_to<vcsn::detail::index_t_impl<vcsn::detail::mutable_automaton_impl<vcsn::context<lal_char, b > >::state_tag> >, std::allocator<vcsn::detail::index_t_impl<vcsn::detail::mutable_automaton_impl<vcsn::context<lal_char, b > >::state_tag> > >)::'lambda'(vcsn::detail::index_t_impl<vcsn::detail::mutable_automaton_impl<vcsn::context<lal_char, b > >::state_tag>), decltype((fp0(fp->null_state())) , (make_fresh_automaton<std::shared_ptr<vcsn::detail::mutable_automaton_impl<vcsn::context<lal_char, b > > >, std::shared_ptr<vcsn::detail::mutable_automaton_impl<vcsn::context<lal_char, b > > > >(fp))) vcsn::copy<std::shared_ptr<vcsn::detail::mutable_automaton_impl<vcsn::context<lal_char, b > > >, std::shared_ptr<vcsn::detail::mutable_automaton_impl<vcsn::context<lal_char, b > > >, decltype((has(fp0fp->null_state())) , (make_fresh_automaton<std::shared_ptr<vcsn::detail::mutable_automaton_impl<vcsn::context<lal_char, b > > >, std::shared_ptr<vcsn::detail::mutable_automaton_impl<vcsn::context<lal_char, b > > > >(fp))) vcsn::copy<std::shared_ptr<vcsn::detail::mutable_automaton_impl<vcsn::context<lal_char, b > > >, std::shared_ptr<vcsn::detail::mutable_automaton_impl<vcsn::context<lal_char, b > > >, std::unordered_set<vcsn::detail::index_t_impl<vcsn::detail::mutable_automaton_impl<vcsn::context<lal_char, b > >::state_tag>, std::hash<vcsn::detail::index_t_impl<vcsn::detail::mutable_automaton_impl<vcsn::context<lal_char, b > >::state_tag> >, std::equal_to<vcsn::detail::index_t_impl<vcsn::detail::mutable_automaton_impl<vcsn::context<lal_char, b > >::state_tag> >, std::allocator<vcsn::detail::index_t_impl<vcsn::detail::mutable_automaton_impl<vcsn::context<lal_char, b > >::state_tag> > > >(std::shared_ptr<vcsn::detail::mutable_automaton_impl<vcsn::context<lal_char, b > > > const&, std::unordered_set<vcsn::detail::index_t_impl<vcsn::detail::mutable_automaton_impl<vcsn::context<lal_char, b > >::state_tag>, std::hash<vcsn::detail::index_t_impl<vcsn::detail::mutable_automaton_impl<vcsn::context<lal_char, b > >::state_tag> >, std::equal_to<vcsn::detail::index_t_impl<vcsn::detail::mutable_automaton_impl<vcsn::context<lal_char, b > >::state_tag> >, std::allocator<vcsn::detail::index_t_impl<vcsn::detail::mutable_automaton_impl<vcsn::context<lal_char, b > >::state_tag> > >)::'lambda'(vcsn::detail::index_t_impl<vcsn::detail::mutable_automaton_impl<vcsn::context<lal_char, b > >::state_tag>)>(std::shared_ptr<vcsn::detail::mutable_automaton_impl<vcsn::context<lal_char, b > > > const&, std::unordered_set<vcsn::detail::index_t_impl<vcsn::detail::mutable_automaton_impl<vcsn::context<lal_char, b > >::state_tag>, std::hash<vcsn::detail::index_t_impl<vcsn::detail::mutable_automaton_impl<vcsn::context<lal_char, b > >::state_tag> >, std::equal_to<vcsn::detail::index_t_impl<vcsn::detail::mutable_automaton_impl<vcsn::context<lal_char, b > >::state_tag> >, std::allocator<vcsn::detail::index_t_impl<vcsn::detail::mutable_automaton_impl<vcsn::context<lal_char, b > >::state_tag> > >)::'lambda'(vcs
''')

check('''/Users/akim/src/lrde/2/vcsn/algos/shortest.hh:83:16: note: in instantiation of function template specialization 'vcsn::detail::enumerater<std::__1::shared_ptr<vcsn::detail::mutable_automaton_impl<vcsn::context<vcsn::nullableset<vcsn::weightset_mixin<vcsn::detail::tupleset_impl<vcsn::letterset<vcsn::set_alphabet<vcsn::char_letters> >, vcsn::weightset_mixin<vcsn::detail::tupleset_impl<vcsn::nullableset<vcsn::letterset<vcsn::set_alphabet<vcsn::char_letters> > >, vcsn::wordset<vcsn::set_alphabet<vcsn::char_letters> > > > > > >, vcsn::weightset_mixin<vcsn::detail::tupleset_impl<vcsn::weightset_mixin<vcsn::rat::expressionset_impl<vcsn::context<vcsn::weightset_mixin<vcsn::detail::tupleset_impl<vcsn::nullableset<vcsn::letterset<vcsn::set_alphabet<vcsn::char_letters> > >, vcsn::nullableset<vcsn::letterset<vcsn::set_alphabet<vcsn::char_letters> > > > >, vcsn::weightset_mixin<vcsn::detail::tupleset_impl<vcsn::weightset_mixin<vcsn::detail::r_impl>, vcsn::weightset_mixin<vcsn::detail::q_impl> > > > > >, vcsn::weightset_mixin<vcsn::detail::tupleset_impl<vcsn::weightset_mixin<vcsn::detail::b_impl>, vcsn::weightset_mixin<vcsn::detail::z_impl> > > > > > > > >::shortest_<vcsn::nullableset<vcsn::weightset_mixin<vcsn::detail::tupleset_impl<vcsn::letterset<vcsn::set_alphabet<vcsn::char_letters> >, vcsn::weightset_mixin<vcsn::detail::tupleset_impl<vcsn::nullableset<vcsn::letterset<vcsn::set_alphabet<vcsn::char_letters> > >, vcsn::wordset<vcsn::set_alphabet<vcsn::char_letters> > > > > > > >' requested here''',
      '''/Users/akim/src/lrde/2/vcsn/algos/shortest.hh:83:16: note: in instantiation of function template specialization 'vcsn::detail::enumerater<mutable_automaton<context<nullableset<tupleset<lal_char, tupleset<nullableset<lal_char >, law_char > > >, tupleset<expressionset<context<tupleset<nullableset<lal_char >, nullableset<lal_char > >, tupleset<r, q > > >, tupleset<b, z > > > > >::shortest_<nullableset<tupleset<lal_char, tupleset<nullableset<lal_char >, law_char > > > >' requested here''',
      '''/Users/akim/src/lrde/2/vcsn/algos/shortest.hh:83:16: note: in instantiation of function template specialization 'vcsn::detail::enumerater<std::shared_ptr<vcsn::detail::mutable_automaton_impl<vcsn::context<vcsn::nullableset<vcsn::weightset_mixin<vcsn::detail::tupleset_impl<lal_char, vcsn::weightset_mixin<vcsn::detail::tupleset_impl<vcsn::nullableset<lal_char >, law_char > > > > >, vcsn::weightset_mixin<vcsn::detail::tupleset_impl<vcsn::weightset_mixin<vcsn::rat::expressionset_impl<vcsn::context<vcsn::weightset_mixin<vcsn::detail::tupleset_impl<vcsn::nullableset<lal_char >, vcsn::nullableset<lal_char > > >, vcsn::weightset_mixin<vcsn::detail::tupleset_impl<r, q > > > > >, vcsn::weightset_mixin<vcsn::detail::tupleset_impl<b, z > > > > > > > >::shortest_<vcsn::nullableset<vcsn::weightset_mixin<vcsn::detail::tupleset_impl<lal_char, vcsn::weightset_mixin<vcsn::detail::tupleset_impl<vcsn::nullableset<lal_char >, law_char > > > > > >' requested here''')


## ------- ##
## sugar.  ##
## ------- ##

def check(input, exp_regex, exp_re):
    '''Check that `sugar(input)` is `exp1` when regex is available,
    otherwise `exp2`.'''
    exp = exp_regex if has_regex else exp_re
    CHECK_EQ(exp, sugar(input))

check('context<nullableset<letterset<char_letters>>, b>',
      '(chars)? → b',
      'nullableset<letterset<chars>>, b')

check('context<letterset<char_letters>, expressionset<context<letterset<char_letters>, b>>>',
      'chars → expressionset<chars → b>',
      'letterset<chars>, expressionset<context<letterset<chars>, b>>')

check('transpose_automaton<mutable_automaton<context<letterset<char_letters>, b>>>',
      'transpose<mutable<chars → b>>',
      'transpose<mutable<context<letterset<chars>, b>>>')

check('name_automaton<mutable_automaton<context<letterset<char_letters>, expressionset<context<letterset<char_letters>, b>>>>>',
      'name<mutable<chars → expressionset<chars → b>>>',
      'name<mutable<context<letterset<chars>, expressionset<context<letterset<chars>, b>>>>>')
