blob: bb8c744f5d84c729a0d4d141f194a8e0a62db470 [file] [log] [blame]
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
Davide Pesaventob5f8bcc2017-02-05 17:58:05 -05003 * Copyright (c) 2014-2017 Regents of the University of California,
4 * Arizona Board of Regents,
5 * Colorado State University,
6 * University Pierre & Marie Curie, Sorbonne University,
7 * Washington University in St. Louis,
8 * Beijing Institute of Technology,
9 * The University of Memphis.
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -070010 *
11 * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
12 *
13 * ndn-cxx library is free software: you can redistribute it and/or modify it under the
14 * terms of the GNU Lesser General Public License as published by the Free Software
15 * Foundation, either version 3 of the License, or (at your option) any later version.
16 *
17 * ndn-cxx library is distributed in the hope that it will be useful, but WITHOUT ANY
18 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
19 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
20 *
21 * You should have received copies of the GNU General Public License and GNU Lesser
22 * General Public License along with ndn-cxx, e.g., in COPYING.md file. If not, see
23 * <http://www.gnu.org/licenses/>.
24 *
25 * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
26 */
27
28#ifndef NDN_UTIL_CONCEPTS_HPP
29#define NDN_UTIL_CONCEPTS_HPP
30
Junxiao Shia4c50482014-12-04 12:40:49 -070031#include "../encoding/block.hpp"
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070032#include "../encoding/encoding-buffer.hpp"
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -070033
Davide Pesaventoeba76ad2017-02-05 02:48:24 -050034#include <boost/concept/usage.hpp>
35#include <boost/type_traits/has_equal_to.hpp>
36#include <boost/type_traits/has_not_equal_to.hpp>
37#include <boost/type_traits/has_left_shift.hpp>
38
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -070039namespace ndn {
40
Junxiao Shia4c50482014-12-04 12:40:49 -070041/** \brief a concept check for TLV abstraction with .wireEncode method
42 */
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -070043template<class X>
44class WireEncodable
45{
46public:
47 BOOST_CONCEPT_USAGE(WireEncodable)
48 {
Junxiao Shia4c50482014-12-04 12:40:49 -070049 Block block = j.wireEncode();
50 block.size(); // avoid 'unused variable block'
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -070051 }
Alexander Afanasyevd5c48e02015-06-24 11:58:14 -070052
53private:
54 X j;
55};
56
57/** \brief a concept check for TLV abstraction with .wireEncode method
58 */
59template<class X>
60class WireEncodableWithEncodingBuffer
61{
62public:
63 BOOST_CONCEPT_USAGE(WireEncodableWithEncodingBuffer)
64 {
65 EncodingEstimator estimator;
66 size_t estimatedSize = j.wireEncode(estimator);
67
68 EncodingBuffer encoder(estimatedSize, 0);
69 j.wireEncode(encoder);
70 }
71
72private:
73 X j;
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -070074};
75
Junxiao Shia4c50482014-12-04 12:40:49 -070076/** \brief a concept check for TLV abstraction with .wireDecode method
77 * and constructible from Block
78 */
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -070079template<class X>
80class WireDecodable
81{
82public:
83 BOOST_CONCEPT_USAGE(WireDecodable)
84 {
85 Block block;
86 X j(block);
87 j.wireDecode(block);
88 }
89};
90
Junxiao Shia4c50482014-12-04 12:40:49 -070091/** \brief a concept check for CryptoPP hash algorithm
92 */
Yingdi Yude222c72014-08-15 16:06:52 -070093template<class X>
94class Hashable
95{
96public:
97 BOOST_CONCEPT_USAGE(Hashable)
98 {
99 X hash;
Yingdi Yude222c72014-08-15 16:06:52 -0700100 uint8_t* buf = 0;
101 size_t size = hash.DigestSize();
102
103 hash.Update(buf, size);
104 hash.Final(buf);
105 hash.Restart();
106 }
107};
108
Davide Pesavento88eb7482017-02-18 19:25:58 -0500109namespace detail {
110
Davide Pesaventoeba76ad2017-02-05 02:48:24 -0500111template<class X>
Davide Pesavento88eb7482017-02-18 19:25:58 -0500112class NfdMgmtProtocolStruct : public WireEncodable<X>
113 , public WireEncodableWithEncodingBuffer<X>
114 , public WireDecodable<X>
Davide Pesaventoeba76ad2017-02-05 02:48:24 -0500115{
116public:
Davide Pesavento88eb7482017-02-18 19:25:58 -0500117 BOOST_CONCEPT_USAGE(NfdMgmtProtocolStruct)
Davide Pesaventoeba76ad2017-02-05 02:48:24 -0500118 {
119 static_assert(std::is_default_constructible<X>::value, "");
120 static_assert(boost::has_equal_to<X, X, bool>::value, "");
121 static_assert(boost::has_not_equal_to<X, X, bool>::value, "");
122 static_assert(boost::has_left_shift<std::ostream, X, std::ostream&>::value, "");
123 static_assert(std::is_base_of<tlv::Error, typename X::Error>::value, "");
124 }
125};
126
Davide Pesavento88eb7482017-02-18 19:25:58 -0500127} // namespace detail
128
129/** \brief concept check for an item in a Status Dataset
130 * \sa https://redmine.named-data.net/projects/nfd/wiki/StatusDataset
131 */
132template<class X>
133class StatusDatasetItem : public detail::NfdMgmtProtocolStruct<X>
134{
135};
136
137/** \brief concept check for an item in a Notification Stream
138 * \sa https://redmine.named-data.net/projects/nfd/wiki/Notification
139 */
140template<class X>
141class NotificationStreamItem : public detail::NfdMgmtProtocolStruct<X>
142{
143};
144
Yingdi Yucbe72b02015-11-25 17:35:37 -0800145// NDN_CXX_ASSERT_DEFAULT_CONSTRUCTIBLE and NDN_CXX_ASSERT_FORWARD_ITERATOR
146// originally written as part of NFD codebase
147
148namespace detail {
149
Davide Pesaventoeba76ad2017-02-05 02:48:24 -0500150// As of Boost 1.61.0, the internal implementation of BOOST_CONCEPT_ASSERT does not allow
Yingdi Yucbe72b02015-11-25 17:35:37 -0800151// multiple assertions on the same line, so we have to combine multiple concepts together.
152
153template<typename T>
154class StlForwardIteratorConcept : public boost::ForwardIterator<T>
155 , public boost::DefaultConstructible<T>
156{
157};
158
159} // namespace detail
160
Davide Pesaventoeba76ad2017-02-05 02:48:24 -0500161// std::is_default_constructible is broken in gcc-4.8, see bug #3882
Yingdi Yucbe72b02015-11-25 17:35:37 -0800162/** \brief assert T is default constructible
163 * \sa http://en.cppreference.com/w/cpp/concept/DefaultConstructible
164 */
165#define NDN_CXX_ASSERT_DEFAULT_CONSTRUCTIBLE(T) \
166 static_assert(std::is_default_constructible<T>::value, \
167 #T " must be default-constructible"); \
168 BOOST_CONCEPT_ASSERT((boost::DefaultConstructible<T>))
169
170/** \brief assert T is a forward iterator
171 * \sa http://en.cppreference.com/w/cpp/concept/ForwardIterator
172 * \note A forward iterator should be default constructible, but boost::ForwardIterator follows
173 * SGI standard which doesn't require DefaultConstructible, so a separate check is needed.
174 */
175#define NDN_CXX_ASSERT_FORWARD_ITERATOR(T) \
Yingdi Yucbe72b02015-11-25 17:35:37 -0800176 static_assert(std::is_default_constructible<T>::value, \
Davide Pesaventoeba76ad2017-02-05 02:48:24 -0500177 #T " must be default-constructible"); \
178 BOOST_CONCEPT_ASSERT((::ndn::detail::StlForwardIteratorConcept<T>))
Yingdi Yucbe72b02015-11-25 17:35:37 -0800179
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -0700180} // namespace ndn
181
182#endif // NDN_UTIL_CONCEPTS_HPP