Fawkes API Fawkes Development Version
change_field.h
1
2/***************************************************************************
3 * change_field.h - Detect whether an update actually changes a field
4 ****************************************************************************/
5
6/* This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version. A runtime exception applies to
10 * this software (see LICENSE.GPL_WRE file mentioned below for details).
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Library General Public License for more details.
16 *
17 * Read the full text in the LICENSE.GPL_WRE file in the doc directory.
18 */
19
20#ifndef _INTERFACE_CHANGE_FIELD_H_
21#define _INTERFACE_CHANGE_FIELD_H_
22
23#include <core/exceptions/software.h>
24
25#include <cstring>
26#include <type_traits>
27
28namespace fawkes {
29
30/** Set a field and return whether it changed
31 * @param field The interface field to change
32 * @param value The new value
33 * @return Whether the new value is different from the old
34 */
35template <class FieldT, class DataT>
36bool
37change_field(FieldT &field, const DataT &value)
38{
39 bool rv = field != value;
40 field = value;
41 return rv;
42}
43
44/** Set a string field and return whether it changed
45 * @param field The interface field to change
46 * @param value The new value
47 * @return Whether the new value is different from the old
48 */
49template <class FieldT, std::size_t Size>
50bool
51change_field(FieldT (&field)[Size], const char *value)
52{
53 bool change = ::strncmp(field, value, Size);
54 ::strncpy(field, value, Size - 1);
55 field[Size - 1] = 0;
56 return change;
57}
58
59/** Set an array field and return whether it changed
60 * @param field The interface field to change
61 * @param value The new value
62 * @return Whether the new value is different from the old
63 */
64template <class FieldT, std::size_t Size, class DataT>
65typename std::enable_if<!std::is_same<FieldT, char>::value, bool>::type
66change_field(FieldT (&field)[Size], const DataT *value)
67{
68 bool change = ::memcmp(field, value, Size);
69 ::memcpy(field, value, sizeof(FieldT) * Size);
70 return change;
71}
72
73/** Set an array field value at a certain index and return whether it changed
74 * @param field The interface field to change
75 * @param index Index into the array field
76 * @param value The new value
77 * @return Whether the new value is different from the old
78 */
79template <class FieldT, std::size_t Size, class DataT>
80bool
81change_field(FieldT (&field)[Size], unsigned int index, const DataT &value)
82{
83 if (index >= Size)
84 throw Exception("Index value %u is out of bounds (0..%u)", index, Size - 1);
85 bool change = field[index] != value;
86 field[index] = value;
87 return change;
88}
89
90} // namespace fawkes
91
92#endif // _INTERFACE_CHANGE_FIELD_H_
Base class for exceptions in Fawkes.
Definition: exception.h:36
Fawkes library namespace.
bool change_field(FieldT &field, const DataT &value)
Set a field and return whether it changed.
Definition: change_field.h:37