tinympl  0.2
mini MPL library for C++11
fused_value_map.hpp
1 // Copyright (C) 2013, Ennio Barbaro.
2 //
3 // Use, modification, and distribution is subject to the Boost Software
4 // License, Version 1.0. (See accompanying file LICENSE_1_0.txt or copy at
5 // http://www.boost.org/LICENSE_1_0.txt)
6 //
7 // See http://sbabbi.github.io/tinympl for documentation.
8 //
9 // You are welcome to contact the author at:
10 // enniobarbaro@gmail.com
11 //
12 
13 #ifndef TINYMPL_FUSED_VALUE_MAP_HPP
14 #define TINYMPL_FUSED_VALUE_MAP_HPP
15 
16 #include <algorithm>
17 #include <tinympl/algorithm_variadic.hpp>
18 
19 namespace tinympl {
20 
21 template<class KeyType,class ValueType,KeyType... Keys>
22 struct fused_value_map
23 {
24  static_assert( variadic::is_unique< std::integral_constant<KeyType,Keys>...>::type::value,"There are duplicate keys");
25 
26  typedef ValueType value_type;
27  typedef value_type* pointer;
28  typedef const value_type* const_pointer;
29  typedef value_type& reference;
30  typedef const value_type& const_reference;
31  typedef value_type* iterator;
32  typedef const value_type* const_iterator;
33  typedef std::size_t size_type;
34  typedef std::ptrdiff_t difference_type;
35  typedef std::reverse_iterator<iterator> reverse_iterator;
36  typedef std::reverse_iterator<const_iterator> const_reverse_iterator;
37 
38  // Capacity.
39  static constexpr size_type size() noexcept { return sizeof ... (Keys); }
40  static constexpr size_type max_size() { return size(); }
41  static constexpr bool empty() noexcept { return size() == 0; }
42 
43  void fill(const value_type& __u) { std::fill_n(begin(), size(), __u); }
44  void swap(fused_value_map& __other) noexcept(noexcept(swap(std::declval<reference>(), std::declval<reference>())))
45  { std::swap_ranges(begin(), end(), __other.begin()); }
46 
47  iterator begin() noexcept
48  { return iterator(data()); }
49 
50  const_iterator begin() const noexcept
51  { return const_iterator(data()); }
52 
53  iterator end() noexcept
54  { return iterator(data() + size()); }
55 
56  const_iterator end() const noexcept
57  { return const_iterator(data() + size()); }
58 
59  reverse_iterator rbegin() noexcept
60  { return reverse_iterator(end()); }
61 
62  const_reverse_iterator rbegin() const noexcept
63  { return const_reverse_iterator(end()); }
64 
65  reverse_iterator rend() noexcept
66  { return reverse_iterator(begin()); }
67 
68  const_reverse_iterator rend() const noexcept
69  { return const_reverse_iterator(begin()); }
70 
71  const_iterator cbegin() const noexcept
72  { return const_iterator(data()); }
73 
74  const_iterator cend() const noexcept
75  { return const_iterator(data() + size()); }
76 
77  const_reverse_iterator crbegin() const noexcept
78  { return const_reverse_iterator(end()); }
79 
80  const_reverse_iterator crend() const noexcept
81  { return const_reverse_iterator(begin()); }
82 
83  template<KeyType k>
84  reference at() {
85  enum {value = variadic::find<
86  std::integral_constant<KeyType,k>,
87  std::integral_constant<KeyType,Keys>...>::type::value};
88  static_assert( value < size(), "Key not present in map");
89  return elems_[value];
90  }
91 
92  template<KeyType k>
93  const_reference at() const {
94  enum {value = variadic::find<
95  std::integral_constant<KeyType,k>,
96  std::integral_constant<KeyType,Keys>...>::type::value};
97  static_assert( value < size(), "Key not present in map");
98  return elems_[value];
99  }
100 
101  pointer data() noexcept { return std::addressof( elems_[0] ); }
102  const_pointer data() const noexcept { return std::addressof( elems_[0] ); }
103 
104  value_type elems_[ size() > 0 ? size() : 1 ];
105 
106  inline friend bool operator==(const fused_value_map & lhs, const fused_value_map & rhs)
107  { return std::equal(lhs.begin(), lhs.end(), rhs.begin()); }
108 
109  inline friend bool operator!=(const fused_value_map & lhs, const fused_value_map & rhs)
110  { return !(lhs == rhs); }
111 
112  inline friend bool operator<(const fused_value_map & lhs, const fused_value_map & rhs)
113  { return std::lexicographical_compare(lhs.begin(), lhs.end(),rhs.begin(), rhs.end()); }
114  inline friend bool operator>(const fused_value_map & lhs, const fused_value_map & rhs)
115  { return rhs < lhs; }
116 
117  inline friend bool operator<=(const fused_value_map & lhs,const fused_value_map & rhs)
118  { return !(lhs > rhs); }
119 
120  inline friend bool operator>=(const fused_value_map & lhs,const fused_value_map & rhs)
121  { return !(lhs < rhs); }
122 };
123 
124 }
125 
126 #endif // TINYMPL_FUSED_VALUE_MAP_HPP