blob: 20d857e52c2de678379eeea99cc73e95c90314fa [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 Pesaventoeba76ad2017-02-05 02:48:24 -0500109/** \brief a concept check for a Status Dataset item
110 * \sa https://redmine.named-data.net/projects/nfd/wiki/StatusDataset
111 */
112template<class X>
113class StatusDatasetItem : public WireEncodable<X>
114 , public WireEncodableWithEncodingBuffer<X>
115 , public WireDecodable<X>
116{
117public:
118 BOOST_CONCEPT_USAGE(StatusDatasetItem)
119 {
120 static_assert(std::is_default_constructible<X>::value, "");
121 static_assert(boost::has_equal_to<X, X, bool>::value, "");
122 static_assert(boost::has_not_equal_to<X, X, bool>::value, "");
123 static_assert(boost::has_left_shift<std::ostream, X, std::ostream&>::value, "");
124 static_assert(std::is_base_of<tlv::Error, typename X::Error>::value, "");
125 }
126};
127
Yingdi Yucbe72b02015-11-25 17:35:37 -0800128// NDN_CXX_ASSERT_DEFAULT_CONSTRUCTIBLE and NDN_CXX_ASSERT_FORWARD_ITERATOR
129// originally written as part of NFD codebase
130
131namespace detail {
132
Davide Pesaventoeba76ad2017-02-05 02:48:24 -0500133// As of Boost 1.61.0, the internal implementation of BOOST_CONCEPT_ASSERT does not allow
Yingdi Yucbe72b02015-11-25 17:35:37 -0800134// multiple assertions on the same line, so we have to combine multiple concepts together.
135
136template<typename T>
137class StlForwardIteratorConcept : public boost::ForwardIterator<T>
138 , public boost::DefaultConstructible<T>
139{
140};
141
142} // namespace detail
143
Davide Pesaventoeba76ad2017-02-05 02:48:24 -0500144// std::is_default_constructible is broken in gcc-4.8, see bug #3882
Yingdi Yucbe72b02015-11-25 17:35:37 -0800145/** \brief assert T is default constructible
146 * \sa http://en.cppreference.com/w/cpp/concept/DefaultConstructible
147 */
148#define NDN_CXX_ASSERT_DEFAULT_CONSTRUCTIBLE(T) \
149 static_assert(std::is_default_constructible<T>::value, \
150 #T " must be default-constructible"); \
151 BOOST_CONCEPT_ASSERT((boost::DefaultConstructible<T>))
152
153/** \brief assert T is a forward iterator
154 * \sa http://en.cppreference.com/w/cpp/concept/ForwardIterator
155 * \note A forward iterator should be default constructible, but boost::ForwardIterator follows
156 * SGI standard which doesn't require DefaultConstructible, so a separate check is needed.
157 */
158#define NDN_CXX_ASSERT_FORWARD_ITERATOR(T) \
Yingdi Yucbe72b02015-11-25 17:35:37 -0800159 static_assert(std::is_default_constructible<T>::value, \
Davide Pesaventoeba76ad2017-02-05 02:48:24 -0500160 #T " must be default-constructible"); \
161 BOOST_CONCEPT_ASSERT((::ndn::detail::StlForwardIteratorConcept<T>))
Yingdi Yucbe72b02015-11-25 17:35:37 -0800162
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -0700163} // namespace ndn
164
165#endif // NDN_UTIL_CONCEPTS_HPP