blob: eec3e09feddbd0ff377758a9f9a390cfe1465964 [file] [log] [blame]
Davide Pesavento25d4f1c2020-04-29 23:31:04 -04001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/*
Davide Pesavento47ce2ee2023-05-09 01:33:33 -04003 * Copyright (c) 2013-2023 Regents of the University of California.
Davide Pesavento25d4f1c2020-04-29 23:31:04 -04004 *
5 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
6 *
7 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
8 * terms of the GNU Lesser General Public License as published by the Free Software
9 * Foundation, either version 3 of the License, or (at your option) any later version.
10 *
11 * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
12 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
13 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
14 *
15 * You should have received copies of the GNU General Public License and GNU Lesser
16 * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
17 * <http://www.gnu.org/licenses/>.
18 *
19 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
20 */
21
Davide Pesavento09904412021-03-24 16:40:53 -040022#ifndef NDN_CXX_TOOLS_NDNSEC_ACCUMULATOR_HPP
23#define NDN_CXX_TOOLS_NDNSEC_ACCUMULATOR_HPP
Davide Pesavento25d4f1c2020-04-29 23:31:04 -040024
25#include <boost/program_options/value_semantic.hpp>
26
Davide Pesavento47ce2ee2023-05-09 01:33:33 -040027namespace ndn::ndnsec {
Davide Pesavento25d4f1c2020-04-29 23:31:04 -040028
29/**
30 * @brief An accumulating option value to handle multiple incrementing options.
31 *
32 * Based on https://gitorious.org/bwy/bwy/source/8753148c324ddfacb1f3cdc315650586bd7b75a4:use/accumulator.hpp
33 * @sa http://benjaminwolsey.de/node/103
34 */
35template<typename T>
36class AccumulatorType : public boost::program_options::value_semantic
37{
38public:
39 explicit
40 AccumulatorType(T* store)
41 : m_store(store)
42 , m_interval(1)
43 , m_default(0)
44 {
45 }
46
47 /// @brief Set the default value for this option.
48 AccumulatorType*
49 setDefaultValue(const T& t)
50 {
51 m_default = t;
52 return this;
53 }
54
55 /**
56 * @brief Set the interval for this option.
57 *
58 * Unlike for program_options::value, this specifies a value
59 * to be applied on each occurrence of the option.
60 */
61 AccumulatorType*
62 setInterval(const T& t)
63 {
64 m_interval = t;
65 return this;
66 }
67
68 std::string
69 name() const final
70 {
Davide Pesavento541a8222022-03-01 15:08:42 -050071 return {};
Davide Pesavento25d4f1c2020-04-29 23:31:04 -040072 }
73
74 // There are no tokens for an AccumulatorType
75 unsigned
76 min_tokens() const final
77 {
78 return 0;
79 }
80
81 unsigned
82 max_tokens() const final
83 {
84 return 0;
85 }
86
87 // Accumulating from different sources is silly.
88 bool
89 is_composing() const final
90 {
91 return false;
92 }
93
94 // Requiring one or more appearances is unlikely.
95 bool
96 is_required() const final
97 {
98 return false;
99 }
100
101 /**
102 * @brief Parse options
103 *
104 * Every appearance of the option simply increments the value
105 * There should never be any tokens.
106 */
107 void
108 parse(boost::any& value_store, const std::vector<std::string>& new_tokens, bool utf8) const final
109 {
110 if (value_store.empty())
111 value_store = T();
112 boost::any_cast<T&>(value_store) += m_interval;
113 }
114
115 /**
116 * @brief If the option doesn't appear, this is the default value.
117 */
118 bool
119 apply_default(boost::any& value_store) const final
120 {
121 value_store = m_default;
122 return true;
123 }
124
125 /**
126 * @brief Notify the user function with the value of the value store.
127 */
128 void
129 notify(const boost::any& value_store) const final
130 {
131 const T* val = boost::any_cast<T>(&value_store);
132 if (m_store)
133 *m_store = *val;
134 }
135
Davide Pesavento25d4f1c2020-04-29 23:31:04 -0400136private:
137 T* m_store;
138 T m_interval;
139 T m_default;
140};
141
142template <typename T>
143AccumulatorType<T>*
144accumulator()
145{
146 return new AccumulatorType<T>(nullptr);
147}
148
149template <typename T>
150AccumulatorType<T>*
151accumulator(T* store)
152{
153 return new AccumulatorType<T>(store);
154}
155
Davide Pesavento47ce2ee2023-05-09 01:33:33 -0400156} // namespace ndn::ndnsec
Davide Pesavento25d4f1c2020-04-29 23:31:04 -0400157
Davide Pesavento09904412021-03-24 16:40:53 -0400158#endif // NDN_CXX_TOOLS_NDNSEC_ACCUMULATOR_HPP