3199ff1b44
[SVN r53730]
150 lines
3.9 KiB
C++
150 lines
3.9 KiB
C++
/* Boost.MultiIndex example of a bidirectional map.
|
|
*
|
|
* Copyright 2003-2009 Joaquin M Lopez Munoz.
|
|
* 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)
|
|
*
|
|
* See http://www.boost.org/libs/multi_index for library home page.
|
|
*/
|
|
|
|
#if !defined(NDEBUG)
|
|
#define BOOST_MULTI_INDEX_ENABLE_INVARIANT_CHECKING
|
|
#define BOOST_MULTI_INDEX_ENABLE_SAFE_MODE
|
|
#endif
|
|
|
|
#include <boost/multi_index_container.hpp>
|
|
#include <boost/multi_index/member.hpp>
|
|
#include <boost/multi_index/ordered_index.hpp>
|
|
#include <iostream>
|
|
#include <string>
|
|
|
|
using boost::multi_index_container;
|
|
using namespace boost::multi_index;
|
|
|
|
/* tags for accessing both sides of a bidirectional map */
|
|
|
|
struct from{};
|
|
struct to{};
|
|
|
|
/* The class template bidirectional_map wraps the specification
|
|
* of a bidirectional map based on multi_index_container.
|
|
*/
|
|
|
|
template<typename FromType,typename ToType>
|
|
struct bidirectional_map
|
|
{
|
|
struct value_type
|
|
{
|
|
value_type(const FromType& first_,const ToType& second_):
|
|
first(first_),second(second_)
|
|
{}
|
|
|
|
FromType first;
|
|
ToType second;
|
|
};
|
|
|
|
#if defined(BOOST_NO_POINTER_TO_MEMBER_TEMPLATE_PARAMETERS) ||\
|
|
defined(BOOST_MSVC)&&(BOOST_MSVC<1300) ||\
|
|
defined(BOOST_INTEL_CXX_VERSION)&&defined(_MSC_VER)&&\
|
|
(BOOST_INTEL_CXX_VERSION<=700)
|
|
|
|
/* see Compiler specifics: Use of member_offset for info on member<> and
|
|
* member_offset<>
|
|
*/
|
|
|
|
BOOST_STATIC_CONSTANT(unsigned,from_offset=offsetof(value_type,first));
|
|
BOOST_STATIC_CONSTANT(unsigned,to_offset =offsetof(value_type,second));
|
|
|
|
typedef multi_index_container<
|
|
value_type,
|
|
indexed_by<
|
|
ordered_unique<
|
|
tag<from>,member_offset<value_type,FromType,from_offset> >,
|
|
ordered_unique<
|
|
tag<to>, member_offset<value_type,ToType,to_offset> >
|
|
>
|
|
> type;
|
|
|
|
#else
|
|
|
|
/* A bidirectional map can be simulated as a multi_index_container
|
|
* of pairs of (FromType,ToType) with two unique indices, one
|
|
* for each member of the pair.
|
|
*/
|
|
|
|
typedef multi_index_container<
|
|
value_type,
|
|
indexed_by<
|
|
ordered_unique<
|
|
tag<from>,member<value_type,FromType,&value_type::first> >,
|
|
ordered_unique<
|
|
tag<to>, member<value_type,ToType,&value_type::second> >
|
|
>
|
|
> type;
|
|
|
|
#endif
|
|
};
|
|
|
|
/* a dictionary is a bidirectional map from strings to strings */
|
|
|
|
typedef bidirectional_map<std::string,std::string>::type dictionary;
|
|
|
|
int main()
|
|
{
|
|
dictionary d;
|
|
|
|
/* Fill up our microdictionary. first members Spanish, second members
|
|
* English.
|
|
*/
|
|
|
|
d.insert(dictionary::value_type("hola","hello"));
|
|
d.insert(dictionary::value_type("adios","goodbye"));
|
|
d.insert(dictionary::value_type("rosa","rose"));
|
|
d.insert(dictionary::value_type("mesa","table"));
|
|
|
|
|
|
std::cout<<"enter a word"<<std::endl;
|
|
std::string word;
|
|
std::getline(std::cin,word);
|
|
|
|
#if defined(BOOST_NO_MEMBER_TEMPLATES) /* use global get<> and family instead */
|
|
|
|
dictionary::iterator it=get<from>(d).find(word);
|
|
if(it!=d.end()){
|
|
std::cout<<word<<" is said "<<it->second<<" in English"<<std::endl;
|
|
}
|
|
else{
|
|
nth_index<dictionary,1>::type::iterator it2=get<1>(d).find(word);
|
|
if(it2!=get<1>(d).end()){
|
|
std::cout<<word<<" is said "<<it2->first<<" in Spanish"<<std::endl;
|
|
}
|
|
else std::cout<<"No such word in the dictionary"<<std::endl;
|
|
}
|
|
|
|
#else
|
|
|
|
/* search the queried word on the from index (Spanish) */
|
|
|
|
dictionary::iterator it=d.get<from>().find(word);
|
|
if(it!=d.end()){ /* found */
|
|
|
|
/* the second part of the element is the equivalent in English */
|
|
|
|
std::cout<<word<<" is said "<<it->second<<" in English"<<std::endl;
|
|
}
|
|
else{
|
|
/* word not found in Spanish, try our luck in English */
|
|
|
|
dictionary::index<to>::type::iterator it2=d.get<to>().find(word);
|
|
if(it2!=d.get<to>().end()){
|
|
std::cout<<word<<" is said "<<it2->first<<" in Spanish"<<std::endl;
|
|
}
|
|
else std::cout<<"No such word in the dictionary"<<std::endl;
|
|
}
|
|
|
|
#endif
|
|
|
|
return 0;
|
|
}
|