summaryrefslogtreecommitdiff
path: root/upb/upb.h
diff options
context:
space:
mode:
authorJosh Haberman <jhaberman@gmail.com>2014-07-02 15:41:10 -0700
committerJosh Haberman <jhaberman@gmail.com>2014-07-02 15:41:10 -0700
commit47b5e0968aa0ec47f522ba357c159b2450645806 (patch)
treed8cd2e7d518b1d6572a6002843446c9e6ee8ef89 /upb/upb.h
parent2d10fa33071d52d7a35ce3b13bc459cd16a0aa33 (diff)
Sync from internal Google development.
Diffstat (limited to 'upb/upb.h')
-rw-r--r--upb/upb.h136
1 files changed, 117 insertions, 19 deletions
diff --git a/upb/upb.h b/upb/upb.h
index c084b19..153b746 100644
--- a/upb/upb.h
+++ b/upb/upb.h
@@ -45,7 +45,10 @@
friend class Pointer<full_class_name>; \
friend class Pointer<const full_class_name>; \
UPB_DISALLOW_COPY_AND_ASSIGN(class_name)
-#else
+#define UPB_ASSERT_STDLAYOUT(type) \
+ static_assert(std::is_standard_layout<type>::value, \
+ #type " must be standard layout");
+#else // !defined(UPB_CXX11)
#define UPB_DISALLOW_COPY_AND_ASSIGN(class_name) \
class_name(const class_name&); \
void operator=(const class_name&);
@@ -56,13 +59,85 @@
friend class Pointer<full_class_name>; \
friend class Pointer<const full_class_name>; \
UPB_DISALLOW_COPY_AND_ASSIGN(class_name)
+#define UPB_ASSERT_STDLAYOUT(type)
#endif
+
#ifdef __cplusplus
+
#define UPB_PRIVATE_FOR_CPP private:
-#else
+#define UPB_DECLARE_TYPE(cppname, cname) typedef cppname cname;
+#define UPB_BEGIN_EXTERN_C extern "C" {
+#define UPB_END_EXTERN_C }
+#define UPB_DEFINE_STRUCT0(cname, members) members;
+#define UPB_DEFINE_STRUCT(cname, cbase, members) \
+ public: \
+ cbase* base() { return &base_; } \
+ const cbase* base() const { return &base_; } \
+ \
+ private: \
+ cbase base_; \
+ members;
+#define UPB_DEFINE_CLASS0(cppname, cppmethods, members) \
+ class cppname { \
+ cppmethods \
+ members \
+ }; \
+ UPB_ASSERT_STDLAYOUT(cppname);
+#define UPB_DEFINE_CLASS1(cppname, cppbase, cppmethods, members) \
+ UPB_DEFINE_CLASS0(cppname, cppmethods, members) \
+ namespace upb { \
+ template <> \
+ class Pointer<cppname> : public PointerBase<cppname, cppbase> { \
+ public: \
+ explicit Pointer(cppname* ptr) : PointerBase(ptr) {} \
+ }; \
+ template <> \
+ class Pointer<const cppname> \
+ : public PointerBase<const cppname, const cppbase> { \
+ public: \
+ explicit Pointer(const cppname* ptr) : PointerBase(ptr) {} \
+ }; \
+ }
+#define UPB_DEFINE_CLASS2(cppname, cppbase, cppbase2, cppmethods, members) \
+ UPB_DEFINE_CLASS0(cppname, UPB_QUOTE(cppmethods), members) \
+ namespace upb { \
+ template <> \
+ class Pointer<cppname> : public PointerBase2<cppname, cppbase, cppbase2> { \
+ public: \
+ explicit Pointer(cppname* ptr) : PointerBase2(ptr) {} \
+ }; \
+ template <> \
+ class Pointer<const cppname> \
+ : public PointerBase2<const cppname, const cppbase, const cppbase2> { \
+ public: \
+ explicit Pointer(const cppname* ptr) : PointerBase2(ptr) {} \
+ }; \
+ }
+
+#else // !defined(__cplusplus)
+
#define UPB_PRIVATE_FOR_CPP
-#endif
+#define UPB_DECLARE_TYPE(cppname, cname) \
+ struct cname; \
+ typedef struct cname cname;
+#define UPB_BEGIN_EXTERN_C
+#define UPB_END_EXTERN_C
+#define UPB_DEFINE_STRUCT0(cname, members) \
+ struct cname { \
+ members; \
+ };
+#define UPB_DEFINE_STRUCT(cname, cbase, members) \
+ struct cname { \
+ cbase base; \
+ members; \
+ };
+#define UPB_DEFINE_CLASS0(cppname, cppmethods, members) members
+#define UPB_DEFINE_CLASS1(cppname, cppbase, cppmethods, members) members
+#define UPB_DEFINE_CLASS2(cppname, cppbase, cppbase2, cppmethods, members) \
+ members
+
+#endif // defined(__cplusplus)
#ifdef __GNUC__
#define UPB_NORETURN __attribute__((__noreturn__))
@@ -75,6 +150,11 @@
#define UPB_UNUSED(var) (void)var
+// Code with commas confuses the preprocessor when passed as arguments, whether
+// C++ type names with commas (eg. Foo<int, int>) or code blocks that declare
+// variables (ie. int foo, bar).
+#define UPB_QUOTE(...) __VA_ARGS__
+
// For asserting something about a variable when the variable is not used for
// anything else. This prevents "unused variable" warnings when compiling in
// debug mode.
@@ -118,6 +198,25 @@ template <class T> class Pointer;
// Casts to any base class, or the type itself (ie. can be a no-op).
template <class T> inline Pointer<T> upcast(T *f) { return Pointer<T>(f); }
+
+template <class T, class Base>
+class PointerBase {
+ public:
+ explicit PointerBase(T* ptr) : ptr_(ptr) {}
+ operator T*() { return ptr_; }
+ operator Base*() { return ptr_->base(); }
+
+ private:
+ T* ptr_;
+};
+
+template <class T, class Base, class Base2>
+class PointerBase2 : public PointerBase<T, Base> {
+ public:
+ explicit PointerBase2(T* ptr) : PointerBase<T, Base>(ptr) {}
+ operator Base2*() { return Pointer<Base>(*this); }
+};
+
}
#endif
@@ -230,13 +329,15 @@ template <class T> class reffed_ptr {
/* upb::Status ****************************************************************/
#ifdef __cplusplus
-namespace upb { class Status; }
-typedef upb::Status upb_status;
-#else
-struct upb_status;
-typedef struct upb_status upb_status;
+namespace upb {
+class ErrorSpace;
+class Status;
+}
#endif
+UPB_DECLARE_TYPE(upb::ErrorSpace, upb_errorspace);
+UPB_DECLARE_TYPE(upb::Status, upb_status);
+
// The maximum length of an error message before it will get truncated.
#define UPB_STATUS_MAX_MESSAGE 128
@@ -245,20 +346,18 @@ typedef struct upb_status upb_status;
// to recover and proceed, but this is not always possible.
typedef bool upb_errcb_t(void *closure, const upb_status* status);
-typedef struct {
+UPB_DEFINE_CLASS0(upb::ErrorSpace,
+,
+UPB_DEFINE_STRUCT0(upb_errorspace,
const char *name;
// Should the error message in the status object according to this code.
void (*set_message)(upb_status* status, int code);
-} upb_errorspace;
-
-#ifdef __cplusplus
-
-typedef upb_errorspace ErrorSpace;
+));
// Object representing a success or failure status.
// It owns no resources and allocates no memory, so it should work
// even in OOM situations.
-class upb::Status {
+UPB_DEFINE_CLASS0(upb::Status,
public:
Status();
@@ -289,9 +388,8 @@ class upb::Status {
private:
UPB_DISALLOW_COPY_AND_ASSIGN(Status);
-#else
-struct upb_status {
-#endif
+,
+UPB_DEFINE_STRUCT0(upb_status,
bool ok_;
// Specific status code defined by some error space (optional).
@@ -300,7 +398,7 @@ struct upb_status {
// Error message; NULL-terminated.
char msg[UPB_STATUS_MAX_MESSAGE];
-};
+));
#define UPB_STATUS_INIT {true, 0, NULL, {0}}
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback