paludis  Version 2.6.0
named_value.hh
1 /* vim: set sw=4 sts=4 et foldmethod=syntax : */
2 
3 /*
4  * Copyright (c) 2008, 2009, 2010 Ciaran McCreesh
5  *
6  * This file is part of the Paludis package manager. Paludis is free software;
7  * you can redistribute it and/or modify it under the terms of the GNU General
8  * Public License version 2, as published by the Free Software Foundation.
9  *
10  * Paludis is distributed in the hope that it will be useful, but WITHOUT ANY
11  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13  * details.
14  *
15  * You should have received a copy of the GNU General Public License along with
16  * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
17  * Place, Suite 330, Boston, MA 02111-1307 USA
18  */
19 
20 #ifndef PALUDIS_GUARD_PALUDIS_UTIL_NAMED_VALUE_HH
21 #define PALUDIS_GUARD_PALUDIS_UTIL_NAMED_VALUE_HH 1
22 
23 #include <paludis/util/named_value-fwd.hh>
24 #include <paludis/util/tribool.hh>
25 #include <utility>
26 #include <type_traits>
27 #include <string>
28 
29 namespace paludis
30 {
31  /**
32  * A NamedValue is used to hold a member of type V_ for a class.
33  *
34  * NamedValue is used to simplify 'plain old data' style classes, and to
35  * provide compiler-time-checked named parameters for functions. Use
36  * thestruct.themember() and thestruct.themember() = to access the real
37  * underlying values.
38  *
39  * Usually a struct containing NamedValue objects will be constructed using
40  * the make_named_values() function. For each NamedValue object,
41  * make_named_values() takes a parameter in the form
42  * <code>n::whatever_K_is() = the_value</code>.
43  *
44  * In all cases, NamedValue members are listed in name-sorted order, and
45  * the same name is used for K_ and the member name.
46  *
47  * \ingroup g_oo
48  */
49  template <typename K_, typename V_>
50  class NamedValue
51  {
52  static_assert(! std::is_reference<V_>::value, "Tried to make a NamedValue hold a reference");
53 
54  private:
55  V_ _value;
56 
57  public:
58  typedef K_ KeyType;
59  typedef V_ ValueType;
60 
61  template <typename T_>
62  NamedValue(const NamedValue<K_, T_> & v) :
63  _value(v())
64  {
65  }
66 
67  template <typename T_>
68  NamedValue(NamedValue<K_, T_> && v) :
69  _value(std::move(v()))
70  {
71  }
72 
73  explicit NamedValue(const V_ & v) :
74  _value(v)
75  {
76  }
77 
78  explicit NamedValue(V_ && v) :
79  _value(v)
80  {
81  }
82 
83  NamedValue(const NamedValue & v) :
84  _value(v._value)
85  {
86  }
87 
88  NamedValue(NamedValue && v) :
89  _value(std::move(v._value))
90  {
91  }
92 
93  NamedValue & operator=(const NamedValue & v)
94  {
95  _value = v._value;
96  return *this;
97  }
98 
99  V_ & operator() ()
100  {
101  return _value;
102  }
103 
104  const V_ & operator() () const
105  {
106  return _value;
107  }
108  };
109 
110  /**
111  * A Name is used to make the assignment for NamedValue keys work.
112  *
113  * \ingroup g_oo
114  */
115  template <typename T_>
116  class Name
117  {
118  public:
119  template <typename V_>
120  NamedValue<Name<T_>, V_> operator= (const V_ & v) const
121  {
122  return NamedValue<Name<T_>, V_>(v);
123  }
124 
125  template <typename V_>
126  NamedValue<Name<T_>, typename std::remove_reference<V_>::type> operator= (V_ && v) const
127  {
128  return NamedValue<Name<T_>, typename std::remove_reference<V_>::type>(v);
129  }
130 
131  NamedValue<Name<T_>, std::string> operator= (const char * const v) const
132  {
133  return NamedValue<Name<T_>, std::string>(std::string(v));
134  }
135 
136  NamedValue<Name<T_>, Tribool> operator= (TriboolIndeterminateValueType) const
137  {
138  return NamedValue<Name<T_>, Tribool>(Tribool(indeterminate));
139  }
140  };
141 }
142 
143 #endif
Definition: about_metadata-fwd.hh:23
STL namespace.