blob: 4b4d7587be80d0db4b15bdef73d90d1352d91cd5 [file] [log] [blame]
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -07001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
Davide Pesavento6717fbd2017-07-09 18:41:35 -04002/*
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
Davide Pesavento88eb7482017-02-18 19:25:58 -050091namespace detail {
92
Davide Pesaventoeba76ad2017-02-05 02:48:24 -050093template<class X>
Davide Pesavento88eb7482017-02-18 19:25:58 -050094class NfdMgmtProtocolStruct : public WireEncodable<X>
95 , public WireEncodableWithEncodingBuffer<X>
96 , public WireDecodable<X>
Davide Pesaventoeba76ad2017-02-05 02:48:24 -050097{
98public:
Davide Pesavento88eb7482017-02-18 19:25:58 -050099 BOOST_CONCEPT_USAGE(NfdMgmtProtocolStruct)
Davide Pesaventoeba76ad2017-02-05 02:48:24 -0500100 {
101 static_assert(std::is_default_constructible<X>::value, "");
102 static_assert(boost::has_equal_to<X, X, bool>::value, "");
103 static_assert(boost::has_not_equal_to<X, X, bool>::value, "");
104 static_assert(boost::has_left_shift<std::ostream, X, std::ostream&>::value, "");
105 static_assert(std::is_base_of<tlv::Error, typename X::Error>::value, "");
106 }
107};
108
Davide Pesavento88eb7482017-02-18 19:25:58 -0500109} // namespace detail
110
111/** \brief concept check for an item in a Status Dataset
112 * \sa https://redmine.named-data.net/projects/nfd/wiki/StatusDataset
113 */
114template<class X>
115class StatusDatasetItem : public detail::NfdMgmtProtocolStruct<X>
116{
117};
118
119/** \brief concept check for an item in a Notification Stream
120 * \sa https://redmine.named-data.net/projects/nfd/wiki/Notification
121 */
122template<class X>
123class NotificationStreamItem : public detail::NfdMgmtProtocolStruct<X>
124{
125};
126
Yingdi Yucbe72b02015-11-25 17:35:37 -0800127// NDN_CXX_ASSERT_DEFAULT_CONSTRUCTIBLE and NDN_CXX_ASSERT_FORWARD_ITERATOR
128// originally written as part of NFD codebase
129
130namespace detail {
131
Davide Pesaventoeba76ad2017-02-05 02:48:24 -0500132// As of Boost 1.61.0, the internal implementation of BOOST_CONCEPT_ASSERT does not allow
Yingdi Yucbe72b02015-11-25 17:35:37 -0800133// multiple assertions on the same line, so we have to combine multiple concepts together.
134
135template<typename T>
136class StlForwardIteratorConcept : public boost::ForwardIterator<T>
137 , public boost::DefaultConstructible<T>
138{
139};
140
141} // namespace detail
142
Davide Pesaventoeba76ad2017-02-05 02:48:24 -0500143// std::is_default_constructible is broken in gcc-4.8, see bug #3882
Yingdi Yucbe72b02015-11-25 17:35:37 -0800144/** \brief assert T is default constructible
145 * \sa http://en.cppreference.com/w/cpp/concept/DefaultConstructible
146 */
147#define NDN_CXX_ASSERT_DEFAULT_CONSTRUCTIBLE(T) \
148 static_assert(std::is_default_constructible<T>::value, \
149 #T " must be default-constructible"); \
150 BOOST_CONCEPT_ASSERT((boost::DefaultConstructible<T>))
151
152/** \brief assert T is a forward iterator
153 * \sa http://en.cppreference.com/w/cpp/concept/ForwardIterator
154 * \note A forward iterator should be default constructible, but boost::ForwardIterator follows
155 * SGI standard which doesn't require DefaultConstructible, so a separate check is needed.
156 */
157#define NDN_CXX_ASSERT_FORWARD_ITERATOR(T) \
Yingdi Yucbe72b02015-11-25 17:35:37 -0800158 static_assert(std::is_default_constructible<T>::value, \
Davide Pesaventoeba76ad2017-02-05 02:48:24 -0500159 #T " must be default-constructible"); \
160 BOOST_CONCEPT_ASSERT((::ndn::detail::StlForwardIteratorConcept<T>))
Yingdi Yucbe72b02015-11-25 17:35:37 -0800161
Alexander Afanasyev4abdbf12014-08-11 12:48:54 -0700162} // namespace ndn
163
164#endif // NDN_UTIL_CONCEPTS_HPP