Add Boost.Test karmic valgrind suppressions
[senf.git] / boost / multi_index / detail / no_duplicate_tags.hpp
1 /* Copyright 2003-2005 Joaquín M López Muñoz.
2  * Distributed under the Boost Software License, Version 1.0.
3  * (See accompanying file LICENSE_1_0.txt or copy at
4  * http://www.boost.org/LICENSE_1_0.txt)
5  *
6  * See http://www.boost.org/libs/multi_index for library home page.
7  */
8
9 #ifndef BOOST_MULTI_INDEX_DETAIL_NO_DUPLICATE_TAGS_HPP
10 #define BOOST_MULTI_INDEX_DETAIL_NO_DUPLICATE_TAGS_HPP
11
12 #if defined(_MSC_VER)&&(_MSC_VER>=1200)
13 #pragma once
14 #endif
15
16 #include <boost/config.hpp> /* keep it first to prevent nasty warns in MSVC */
17 #include <boost/mpl/fold.hpp>
18 #include <boost/mpl/set/set0.hpp>
19
20 namespace boost{
21
22 namespace multi_index{
23
24 namespace detail{
25
26 /* no_duplicate_tags check at compile-time that a tag list
27  * has no duplicate tags.
28  * The algorithm deserves some explanation: tags
29  * are sequentially inserted into a mpl::set if they were
30  * not already present. Due to the magic of mpl::set
31  * (mpl::has_key is contant time), this operation takes linear
32  * time, and even MSVC++ 6.5 handles it gracefully (other obvious
33  * solutions are quadratic.)
34  */
35
36 struct duplicate_tag_mark{};
37
38 struct duplicate_tag_marker
39 {
40   template <typename MplSet,typename Tag>
41   struct apply
42   {
43     typedef mpl::s_item<
44       typename mpl::if_<mpl::has_key<MplSet,Tag>,duplicate_tag_mark,Tag>::type,
45       MplSet
46     > type;
47   };
48 };
49
50 template<typename TagList>
51 struct no_duplicate_tags
52 {
53   typedef typename mpl::fold<
54     TagList,
55     mpl::set0<>,
56     duplicate_tag_marker
57   >::type aux;
58  
59   BOOST_STATIC_CONSTANT(
60     bool,value=!(mpl::has_key<aux,duplicate_tag_mark>::value));
61 };
62
63 /* Variant for an index list: duplication is checked
64  * across all the indices.
65  */
66
67 struct duplicate_tag_list_marker
68 {
69   template <typename MplSet,typename Index>
70   struct apply:mpl::fold<
71     BOOST_DEDUCED_TYPENAME Index::tag_list,
72     MplSet,
73     duplicate_tag_marker>
74   {
75   };
76 };
77
78 template<typename IndexList>
79 struct no_duplicate_tags_in_index_list
80 {
81   typedef typename mpl::fold<
82     IndexList,
83     mpl::set0<>,
84     duplicate_tag_list_marker
85   >::type aux;
86  
87   BOOST_STATIC_CONSTANT(
88     bool,value=!(mpl::has_key<aux,duplicate_tag_mark>::value));
89 };
90
91 } /* namespace multi_index::detail */
92
93 } /* namespace multi_index */
94
95 } /* namespace boost */
96
97 #endif