你去:
struct Terminal;
template < typename Trie, typename First, typename Last,
typename Enable = void >
struct insertInTrie_impl
{
typedef typename
mpl::deref<First>::type key;
typedef typename
mpl::at<
Trie,
key
>::type subTrieOrVoid; // would be easier if "at" supported Default
typedef typename
mpl::if_<
boost::is_same< subTrieOrVoid, mpl::void_ >,
mpl::map<>,
subTrieOrVoid
>::type subTrie;
typedef typename
mpl::insert<
Trie,
mpl::pair<
key, typename
insertInTrie_impl<
subTrie, typename
mpl::next<First>::type,
Last
>::type
>
>::type type;
};
template < typename Trie, typename First, typename Last >
struct insertInTrie_impl< Trie, First, Last, typename
boost::enable_if< boost::is_same<First, Last> >::type >
: mpl::insert<
Trie,
mpl::pair< Terminal, Terminal >
// I'm not sure what you want in your terminal node
>
{};
template < typename Trie, typename Seq >
struct insertInTrie
: insertInTrie_impl<
Trie, typename
mpl::begin<Seq>::type, typename
mpl::end<Seq>::type
>
{};
template < typename SeqOfSeq >
struct constructTrie
: mpl::fold<
SeqOfSeq,
mpl::map<>,
insertInTrie< mpl::_1, mpl::_2 >
>
{};
insertInTrie_impl
是一个递归元函数,它使用迭代器将序列插入到现有的 trie 中。insertInTrie
接受一个调用序列insertInTrie_impl
。constructTrie
适用insertInTrie
于给定序列中的所有序列,从一个空的 trie 开始。
在伪代码中,如下所示:
Trie insertInTrie_impl(trie, first, last)
{
if (first == last)
{
trie.insert(Terminal, Terminal);
return trie;
}
key = *first;
subTrie = trie[key];
if (subTrie = void) // key not found
{
subTrie = emptyTrie;
}
trie.insert(key, insertInTrie_impl(subTrie, ++first, last))
return trie;
}
Trie insertInTrie(trie, seq)
{
return insertInTrie_impl(trie, seq.begin(), seq.end();
}
Trie constructTrie(seqOfSeq)
{
return fold(seqOfSeq, emptyTrie, insertInTrie);
}
最后,一个示例使用:
int main()
{
typedef mpl::vector<
mpl::vector<mpl::_1, mpl::_2>,
mpl::vector<mpl::_1, mpl::_2, mpl::_3>,
mpl::vector<mpl::_2, mpl::_1>,
mpl::vector<mpl::_2, mpl::_2>,
mpl::vector<mpl::_2, mpl::_2, mpl::_3>
> seqOfSeq;
typedef constructTrie< seqOfSeq >::type bigTrie;
BOOST_MPL_ASSERT((
mpl::has_key<
mpl::at<
mpl::at<
bigTrie,
mpl::_1
>::type,
mpl::_2
>::type,
Terminal
> ));
BOOST_MPL_ASSERT((
mpl::has_key<
mpl::at<
mpl::at<
mpl::at<
bigTrie,
mpl::_1
>::type,
mpl::_2
>::type,
mpl::_3
>::type,
Terminal
> ));
BOOST_MPL_ASSERT((
mpl::has_key<
mpl::at<
mpl::at<
bigTrie,
mpl::_2
>::type,
mpl::_2
>::type,
Terminal
> ));
}