IMP logo
IMP Reference Guide  develop.e004443c3b,2024/04/25
The Integrative Modeling Platform
set_map_macros.h
Go to the documentation of this file.
1 /**
2  * \file IMP/set_map_macros.h
3  * \brief Macros to choose the best set or map for different purposes.
4  *
5  * Copyright 2007-2022 IMP Inventors. All rights reserved.
6  *
7  */
8 
9 #ifndef IMPKERNEL_SET_MAP_MACROS_H
10 #define IMPKERNEL_SET_MAP_MACROS_H
11 
12 #ifdef IMP_DOXYGEN
13 //! Macro to support platform independent declaration of a small ordered set
14 /** Declare a small, ordered set like IMP_KERNEL_SMALL_ORDERED_SET<item>. */
15 #define IMP_KERNEL_SMALL_ORDERED_SET boost::container::flat_set
16 //! Macro to support platform independent declaration of a small ordered map
17 /** Declare a small, ordered set like IMP_KERNEL_SMALL_ORDERED_MAP<key, value>. */
18 #define IMP_KERNEL_SMALL_ORDERED_MAP boost::container::flat_map
19 //! Macro to support platform independent declaration of a small unordered set
20 /** Declare a small, ordered set like IMP_KERNEL_SMALL_UNORDERED_SET<item>. */
21 #define IMP_KERNEL_SMALL_UNORDERED_SET boost::container::flat_set
22 //! Macro to support platform independent declaration of a small unordered map
23 /** Declare a small, ordered set like IMP_KERNEL_SMALL_UNORDERED_MAP<key, value>.
24  */
25 #define IMP_KERNEL_SMALL_UNORDERED_MAP boost::container::flat_map
26 //! Macro to support platform independent declaration of a large ordered set
27 /** Declare a small, ordered set like IMP_KERNEL_LARGE_ORDERED_SET<item>. */
28 #define IMP_KERNEL_LARGE_ORDERED_SET std::set
29 //! Macro to support platform independent declaration of a large ordered map
30 /** Declare a small, ordered set like IMP_KERNEL_LARGE_ORDERED_MAP<key, value>. */
31 #define IMP_KERNEL_LARGE_ORDERED_MAP std::map
32 //! Macro to support platform independent declaration of a large unordered set
33 /** Declare a small, ordered set like IMP_KERNEL_LARGE_UNORDERED_SET<item>. */
34 #define IMP_KERNEL_LARGE_UNORDERED_SET boost::unordered_set
35 //! Macro to support platform independent declaration of a large unordered map
36 /** Declare a small, ordered set like IMP_KERNEL_LARGE_UNORDERED_MAP<key, value>.
37  */
38 #define IMP_KERNEL_LARGE_UNORDERED_MAP boost::unordered_map
39 
40 #else
41 
42 #include <IMP/kernel_config.h>
43 #include <boost/version.hpp>
44 #include <boost/functional/hash/hash.hpp> // IWYU pragma: export
45 
46 #include <boost/functional/hash/hash.hpp> // IWYU pragma: export
47 #include <set> // IWYU pragma: export
48 #include <map> // IWYU pragma: export
49 #include <boost/unordered_set.hpp> // IWYU pragma: export
50 #include <boost/unordered_map.hpp> // IWYU pragma: export
51 
52 #define IMP_KERNEL_LARGE_ORDERED_SET std::set
53 #define IMP_KERNEL_LARGE_ORDERED_MAP std::map
54 #define IMP_KERNEL_LARGE_UNORDERED_SET boost::unordered_set
55 #define IMP_KERNEL_LARGE_UNORDERED_MAP boost::unordered_map
56 
57 // Use cereal's own functions to serialize unordered_map, not those
58 // provided (for Boost.Serialize) in newer Boost versions
59 namespace cereal {
60  template<class Archive, class Key, class T>
61  struct specialize<Archive, boost::unordered_map<Key, T>,
62  cereal::specialization::non_member_load_save> {};
63 }
64 
65 #if defined(_MSC_VER) && _MSC_VER <= 1500
66 #include <set> // IWYU pragma: export
67 #include <map> // IWYU pragma: export
68 #include <boost/unordered_set.hpp> // IWYU pragma: export
69 #include <boost/unordered_map.hpp> // IWYU pragma: export
70 
71 #define IMP_KERNEL_SMALL_ORDERED_SET std::set
72 #define IMP_KERNEL_SMALL_ORDERED_MAP std::map
73 #define IMP_KERNEL_SMALL_UNORDERED_SET boost::unordered_set
74 #define IMP_KERNEL_SMALL_UNORDERED_MAP boost::unordered_map
75 #else
76 #include <boost/container/flat_set.hpp> // IWYU pragma: export
77 #include <boost/container/flat_map.hpp> // IWYU pragma: export
78 #include <cereal/access.hpp>
79 #define IMP_KERNEL_SMALL_ORDERED_SET boost::container::flat_set
80 #define IMP_KERNEL_SMALL_ORDERED_MAP boost::container::flat_map
81 #define IMP_KERNEL_SMALL_UNORDERED_SET boost::container::flat_set
82 #define IMP_KERNEL_SMALL_UNORDERED_MAP boost::container::flat_map
83 
84 // Allow serialization of boost::container::flat_set
85 namespace cereal {
86  template<class Archive, typename Key, typename Compare, typename Allocator>
87  inline void save(Archive &ar,
88  boost::container::flat_set<Key, Compare, Allocator> const &t) {
89  auto count = t.size();
90  ar(count);
91  typename boost::container::flat_set<
92  Key, Compare, Allocator>::const_iterator it = t.begin();
93  while(count-- > 0) {
94  ar(*it++);
95  }
96  }
97 
98  template<class Archive, typename Key, typename Compare, typename Allocator>
99  inline void load(Archive &ar,
100  boost::container::flat_set<Key, Compare, Allocator> &t) {
101  typedef typename boost::container::flat_set<Key, Compare, Allocator>::iterator iterator;
102  typedef typename boost::container::flat_set<Key, Compare, Allocator>::value_type value_type;
103  t.clear();
104  typename boost::container::flat_set<Key, Compare, Allocator>::size_type count;
105  ar(count);
106  iterator hint = t.begin();
107  while(count-- > 0) {
108  value_type key;
109  ar(key);
110  hint = t.insert(hint, key);
111  }
112  }
113 }
114 
115 #endif
116 #endif
117 
118 #endif /* IMPKERNEL_SET_MAP_MACROS_H */