capnproto

FORK: Cap'n Proto serialization/RPC system - core tools and C++ library
git clone https://git.neptards.moe/neptards/capnproto.git
Log | Files | Refs | README | LICENSE

generated-header-support.h (13682B)


      1 // Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors
      2 // Licensed under the MIT License:
      3 //
      4 // Permission is hereby granted, free of charge, to any person obtaining a copy
      5 // of this software and associated documentation files (the "Software"), to deal
      6 // in the Software without restriction, including without limitation the rights
      7 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
      8 // copies of the Software, and to permit persons to whom the Software is
      9 // furnished to do so, subject to the following conditions:
     10 //
     11 // The above copyright notice and this permission notice shall be included in
     12 // all copies or substantial portions of the Software.
     13 //
     14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     19 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     20 // THE SOFTWARE.
     21 
     22 // This file is included from all generated headers.
     23 
     24 #pragma once
     25 
     26 #include "raw-schema.h"
     27 #include "layout.h"
     28 #include "list.h"
     29 #include "orphan.h"
     30 #include "pointer-helpers.h"
     31 #include "any.h"
     32 #include <kj/string.h>
     33 #include <kj/string-tree.h>
     34 #include <kj/hash.h>
     35 
     36 CAPNP_BEGIN_HEADER
     37 
     38 namespace capnp {
     39 
     40 class MessageBuilder;  // So that it can be declared a friend.
     41 
     42 template <typename T, Kind k = CAPNP_KIND(T)>
     43 struct ToDynamic_;   // Defined in dynamic.h, needs to be declared as everyone's friend.
     44 
     45 struct DynamicStruct;  // So that it can be declared a friend.
     46 
     47 struct Capability;  // To declare brandBindingFor<Capability>()
     48 
     49 namespace _ {  // private
     50 
     51 #if !CAPNP_LITE
     52 
     53 template <typename T, typename CapnpPrivate = typename T::_capnpPrivate, bool = false>
     54 inline const RawSchema& rawSchema() {
     55   return *CapnpPrivate::schema;
     56 }
     57 template <typename T, uint64_t id = schemas::EnumInfo<T>::typeId>
     58 inline const RawSchema& rawSchema() {
     59   return *schemas::EnumInfo<T>::schema;
     60 }
     61 
     62 template <typename T, typename CapnpPrivate = typename T::_capnpPrivate>
     63 inline const RawBrandedSchema& rawBrandedSchema() {
     64   return *CapnpPrivate::brand();
     65 }
     66 template <typename T, uint64_t id = schemas::EnumInfo<T>::typeId>
     67 inline const RawBrandedSchema& rawBrandedSchema() {
     68   return schemas::EnumInfo<T>::schema->defaultBrand;
     69 }
     70 
     71 template <typename TypeTag, typename... Params>
     72 struct ChooseBrand;
     73 // If all of `Params` are `AnyPointer`, return the type's default brand. Otherwise, return a
     74 // specific brand instance. TypeTag is the _capnpPrivate struct for the type in question.
     75 
     76 template <typename TypeTag>
     77 struct ChooseBrand<TypeTag> {
     78   // All params were AnyPointer. No specific brand needed.
     79   static constexpr _::RawBrandedSchema const* brand() { return &TypeTag::schema->defaultBrand; }
     80 };
     81 
     82 template <typename TypeTag, typename... Rest>
     83 struct ChooseBrand<TypeTag, AnyPointer, Rest...>: public ChooseBrand<TypeTag, Rest...> {};
     84 // The first parameter is AnyPointer, so recurse to check the rest.
     85 
     86 template <typename TypeTag, typename First, typename... Rest>
     87 struct ChooseBrand<TypeTag, First, Rest...> {
     88   // At least one parameter is not AnyPointer, so use the specificBrand constant.
     89   static constexpr _::RawBrandedSchema const* brand() { return &TypeTag::specificBrand; }
     90 };
     91 
     92 template <typename T, Kind k = kind<T>()>
     93 struct BrandBindingFor_;
     94 
     95 #define HANDLE_TYPE(Type, which) \
     96   template <> \
     97   struct BrandBindingFor_<Type, Kind::PRIMITIVE> { \
     98     static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) { \
     99       return { which, listDepth, nullptr }; \
    100     } \
    101   }
    102 HANDLE_TYPE(Void, 0);
    103 HANDLE_TYPE(bool, 1);
    104 HANDLE_TYPE(int8_t, 2);
    105 HANDLE_TYPE(int16_t, 3);
    106 HANDLE_TYPE(int32_t, 4);
    107 HANDLE_TYPE(int64_t, 5);
    108 HANDLE_TYPE(uint8_t, 6);
    109 HANDLE_TYPE(uint16_t, 7);
    110 HANDLE_TYPE(uint32_t, 8);
    111 HANDLE_TYPE(uint64_t, 9);
    112 HANDLE_TYPE(float, 10);
    113 HANDLE_TYPE(double, 11);
    114 #undef HANDLE_TYPE
    115 
    116 template <>
    117 struct BrandBindingFor_<Text, Kind::BLOB> {
    118   static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) {
    119     return { 12, listDepth, nullptr };
    120   }
    121 };
    122 
    123 template <>
    124 struct BrandBindingFor_<Data, Kind::BLOB> {
    125   static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) {
    126     return { 13, listDepth, nullptr };
    127   }
    128 };
    129 
    130 template <typename T>
    131 struct BrandBindingFor_<List<T>, Kind::LIST> {
    132   static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) {
    133     return BrandBindingFor_<T>::get(listDepth + 1);
    134   }
    135 };
    136 
    137 template <typename T>
    138 struct BrandBindingFor_<T, Kind::ENUM> {
    139   static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) {
    140     return { 15, listDepth, nullptr };
    141   }
    142 };
    143 
    144 template <typename T>
    145 struct BrandBindingFor_<T, Kind::STRUCT> {
    146   static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) {
    147     return { 16, listDepth, T::_capnpPrivate::brand() };
    148   }
    149 };
    150 
    151 template <typename T>
    152 struct BrandBindingFor_<T, Kind::INTERFACE> {
    153   static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) {
    154     return { 17, listDepth, T::_capnpPrivate::brand() };
    155   }
    156 };
    157 
    158 template <>
    159 struct BrandBindingFor_<AnyPointer, Kind::OTHER> {
    160   static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) {
    161     return { 18, listDepth, 0, 0 };
    162   }
    163 };
    164 
    165 template <>
    166 struct BrandBindingFor_<AnyStruct, Kind::OTHER> {
    167   static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) {
    168     return { 18, listDepth, 0, 1 };
    169   }
    170 };
    171 
    172 template <>
    173 struct BrandBindingFor_<AnyList, Kind::OTHER> {
    174   static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) {
    175     return { 18, listDepth, 0, 2 };
    176   }
    177 };
    178 
    179 template <>
    180 struct BrandBindingFor_<Capability, Kind::OTHER> {
    181   static constexpr RawBrandedSchema::Binding get(uint16_t listDepth) {
    182     return { 18, listDepth, 0, 3 };
    183   }
    184 };
    185 
    186 template <typename T>
    187 constexpr RawBrandedSchema::Binding brandBindingFor() {
    188   return BrandBindingFor_<T>::get(0);
    189 }
    190 
    191 kj::StringTree structString(StructReader reader, const RawBrandedSchema& schema);
    192 kj::String enumString(uint16_t value, const RawBrandedSchema& schema);
    193 // Declared here so that we can declare inline stringify methods on generated types.
    194 // Defined in stringify.c++, which depends on dynamic.c++, which is allowed not to be linked in.
    195 
    196 template <typename T>
    197 inline kj::StringTree structString(StructReader reader) {
    198   return structString(reader, rawBrandedSchema<T>());
    199 }
    200 template <typename T>
    201 inline kj::String enumString(T value) {
    202   return enumString(static_cast<uint16_t>(value), rawBrandedSchema<T>());
    203 }
    204 
    205 #endif  // !CAPNP_LITE
    206 
    207 // TODO(cleanup):  Unify ConstStruct and ConstList.
    208 template <typename T>
    209 class ConstStruct {
    210 public:
    211   ConstStruct() = delete;
    212   KJ_DISALLOW_COPY(ConstStruct);
    213   inline explicit constexpr ConstStruct(const word* ptr): ptr(ptr) {}
    214 
    215   inline typename T::Reader get() const {
    216     return AnyPointer::Reader(PointerReader::getRootUnchecked(ptr)).getAs<T>();
    217   }
    218 
    219   inline operator typename T::Reader() const { return get(); }
    220   inline typename T::Reader operator*() const { return get(); }
    221   inline TemporaryPointer<typename T::Reader> operator->() const { return get(); }
    222 
    223 private:
    224   const word* ptr;
    225 };
    226 
    227 template <typename T>
    228 class ConstList {
    229 public:
    230   ConstList() = delete;
    231   KJ_DISALLOW_COPY(ConstList);
    232   inline explicit constexpr ConstList(const word* ptr): ptr(ptr) {}
    233 
    234   inline typename List<T>::Reader get() const {
    235     return AnyPointer::Reader(PointerReader::getRootUnchecked(ptr)).getAs<List<T>>();
    236   }
    237 
    238   inline operator typename List<T>::Reader() const { return get(); }
    239   inline typename List<T>::Reader operator*() const { return get(); }
    240   inline TemporaryPointer<typename List<T>::Reader> operator->() const { return get(); }
    241 
    242 private:
    243   const word* ptr;
    244 };
    245 
    246 template <size_t size>
    247 class ConstText {
    248 public:
    249   ConstText() = delete;
    250   KJ_DISALLOW_COPY(ConstText);
    251   inline explicit constexpr ConstText(const word* ptr): ptr(ptr) {}
    252 
    253   inline Text::Reader get() const {
    254     return Text::Reader(reinterpret_cast<const char*>(ptr), size);
    255   }
    256 
    257   inline operator Text::Reader() const { return get(); }
    258   inline Text::Reader operator*() const { return get(); }
    259   inline TemporaryPointer<Text::Reader> operator->() const { return get(); }
    260 
    261   inline kj::StringPtr toString() const {
    262     return get();
    263   }
    264 
    265 private:
    266   const word* ptr;
    267 };
    268 
    269 template <size_t size>
    270 inline kj::StringPtr KJ_STRINGIFY(const ConstText<size>& s) {
    271   return s.get();
    272 }
    273 
    274 template <size_t size>
    275 class ConstData {
    276 public:
    277   ConstData() = delete;
    278   KJ_DISALLOW_COPY(ConstData);
    279   inline explicit constexpr ConstData(const word* ptr): ptr(ptr) {}
    280 
    281   inline Data::Reader get() const {
    282     return Data::Reader(reinterpret_cast<const byte*>(ptr), size);
    283   }
    284 
    285   inline operator Data::Reader() const { return get(); }
    286   inline Data::Reader operator*() const { return get(); }
    287   inline TemporaryPointer<Data::Reader> operator->() const { return get(); }
    288 
    289 private:
    290   const word* ptr;
    291 };
    292 
    293 template <size_t size>
    294 inline auto KJ_STRINGIFY(const ConstData<size>& s) -> decltype(kj::toCharSequence(s.get())) {
    295   return kj::toCharSequence(s.get());
    296 }
    297 
    298 }  // namespace _ (private)
    299 
    300 template <typename T, typename CapnpPrivate = typename T::_capnpPrivate>
    301 inline constexpr uint64_t typeId() { return CapnpPrivate::typeId; }
    302 template <typename T, uint64_t id = schemas::EnumInfo<T>::typeId>
    303 inline constexpr uint64_t typeId() { return id; }
    304 // typeId<MyType>() returns the type ID as defined in the schema.  Works with structs, enums, and
    305 // interfaces.
    306 
    307 template <typename T>
    308 inline constexpr uint sizeInWords() {
    309   // Return the size, in words, of a Struct type, if allocated free-standing (not in a list).
    310   // May be useful for pre-computing space needed in order to precisely allocate messages.
    311 
    312   return unbound((upgradeBound<uint>(_::structSize<T>().data) +
    313       _::structSize<T>().pointers * WORDS_PER_POINTER) / WORDS);
    314 }
    315 
    316 }  // namespace capnp
    317 
    318 #if _MSC_VER && !defined(__clang__)
    319 // MSVC doesn't understand floating-point constexpr yet.
    320 //
    321 // TODO(msvc): Remove this hack when MSVC is fixed.
    322 #define CAPNP_NON_INT_CONSTEXPR_DECL_INIT(value)
    323 #define CAPNP_NON_INT_CONSTEXPR_DEF_INIT(value) = value
    324 #else
    325 #define CAPNP_NON_INT_CONSTEXPR_DECL_INIT(value) = value
    326 #define CAPNP_NON_INT_CONSTEXPR_DEF_INIT(value)
    327 #endif
    328 
    329 #if _MSC_VER && !defined(__clang__)
    330 // TODO(msvc): A little hack to allow MSVC to use C++14 return type deduction in cases where the
    331 // explicit type exposes bugs in the compiler.
    332 #define CAPNP_AUTO_IF_MSVC(...) auto
    333 #else
    334 #define CAPNP_AUTO_IF_MSVC(...) __VA_ARGS__
    335 #endif
    336 
    337 #if CAPNP_LITE
    338 
    339 #define CAPNP_DECLARE_SCHEMA(id) \
    340     extern ::capnp::word const* const bp_##id
    341 
    342 #define CAPNP_DECLARE_ENUM(type, id) \
    343     inline ::kj::String KJ_STRINGIFY(type##_##id value) { \
    344       return ::kj::str(static_cast<uint16_t>(value)); \
    345     } \
    346     template <> struct EnumInfo<type##_##id> { \
    347       struct IsEnum; \
    348       static constexpr uint64_t typeId = 0x##id; \
    349       static inline ::capnp::word const* encodedSchema() { return bp_##id; } \
    350     }
    351 
    352 #if _MSC_VER && !defined(__clang__)
    353 // TODO(msvc): MSVC doesn't expect constexprs to have definitions.
    354 #define CAPNP_DEFINE_ENUM(type, id)
    355 #else
    356 #define CAPNP_DEFINE_ENUM(type, id) \
    357     constexpr uint64_t EnumInfo<type>::typeId
    358 #endif
    359 
    360 #define CAPNP_DECLARE_STRUCT_HEADER(id, dataWordSize_, pointerCount_) \
    361       struct IsStruct; \
    362       static constexpr uint64_t typeId = 0x##id; \
    363       static constexpr uint16_t dataWordSize = dataWordSize_; \
    364       static constexpr uint16_t pointerCount = pointerCount_; \
    365       static inline ::capnp::word const* encodedSchema() { return ::capnp::schemas::bp_##id; }
    366 
    367 #else  // CAPNP_LITE
    368 
    369 #define CAPNP_DECLARE_SCHEMA(id) \
    370     extern ::capnp::word const* const bp_##id; \
    371     extern const ::capnp::_::RawSchema s_##id
    372 
    373 #define CAPNP_DECLARE_ENUM(type, id) \
    374     inline ::kj::String KJ_STRINGIFY(type##_##id value) { \
    375       return ::capnp::_::enumString(value); \
    376     } \
    377     template <> struct EnumInfo<type##_##id> { \
    378       struct IsEnum; \
    379       static constexpr uint64_t typeId = 0x##id; \
    380       static inline ::capnp::word const* encodedSchema() { return bp_##id; } \
    381       static constexpr ::capnp::_::RawSchema const* schema = &s_##id; \
    382     }
    383 #define CAPNP_DEFINE_ENUM(type, id) \
    384     constexpr uint64_t EnumInfo<type>::typeId; \
    385     constexpr ::capnp::_::RawSchema const* EnumInfo<type>::schema
    386 
    387 #define CAPNP_DECLARE_STRUCT_HEADER(id, dataWordSize_, pointerCount_) \
    388       struct IsStruct; \
    389       static constexpr uint64_t typeId = 0x##id; \
    390       static constexpr ::capnp::Kind kind = ::capnp::Kind::STRUCT; \
    391       static constexpr uint16_t dataWordSize = dataWordSize_; \
    392       static constexpr uint16_t pointerCount = pointerCount_; \
    393       static inline ::capnp::word const* encodedSchema() { return ::capnp::schemas::bp_##id; } \
    394       static constexpr ::capnp::_::RawSchema const* schema = &::capnp::schemas::s_##id;
    395 
    396 #define CAPNP_DECLARE_INTERFACE_HEADER(id) \
    397       struct IsInterface; \
    398       static constexpr uint64_t typeId = 0x##id; \
    399       static constexpr ::capnp::Kind kind = ::capnp::Kind::INTERFACE; \
    400       static inline ::capnp::word const* encodedSchema() { return ::capnp::schemas::bp_##id; } \
    401       static constexpr ::capnp::_::RawSchema const* schema = &::capnp::schemas::s_##id;
    402 
    403 #endif  // CAPNP_LITE, else
    404 
    405 namespace capnp {
    406 namespace schemas {
    407 CAPNP_DECLARE_SCHEMA(995f9a3377c0b16e);
    408 // HACK: Forward-declare the RawSchema for StreamResult, from stream.capnp. This allows capnp
    409 //   files which declare streaming methods to avoid including stream.capnp.h.
    410 }
    411 }
    412 
    413 CAPNP_END_HEADER