/*
- * Copyright 2015 Facebook, Inc.
+ * Copyright 2011-present Facebook, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* limitations under the License.
*/
-#ifndef FOLLY_PACKEDSYNCPTR_H_
-#define FOLLY_PACKEDSYNCPTR_H_
+#pragma once
+
+#include <type_traits>
+
+#include <glog/logging.h>
#include <folly/Portability.h>
+#include <folly/SmallLocks.h>
-#if !FOLLY_X64 && !FOLLY_PPC64
-# error "PackedSyncPtr is x64 and ppc64 specific code."
+#if !FOLLY_X64 && !FOLLY_PPC64 && !FOLLY_AARCH64
+#error "PackedSyncPtr is x64, ppc64 or aarch64 specific code."
#endif
/*
* @author Jordan DeLong <delong.j@fb.com>
*/
-#include <folly/SmallLocks.h>
-#include <type_traits>
-#include <glog/logging.h>
-
namespace folly {
-template<class T>
+template <class T>
class PackedSyncPtr {
// This just allows using this class even with T=void. Attempting
// to use the operator* or operator[] on a PackedSyncPtr<void> will
// still properly result in a compile error.
typedef typename std::add_lvalue_reference<T>::type reference;
-public:
+ public:
/*
* If you default construct one of these, you must call this init()
* function before using it.
* (We are avoiding a constructor to ensure gcc allows us to put
* this class in packed structures.)
*/
- void init(T* initialPtr = 0, uint16_t initialExtra = 0) {
+ void init(T* initialPtr = nullptr, uint16_t initialExtra = 0) {
auto intPtr = reinterpret_cast<uintptr_t>(initialPtr);
CHECK(!(intPtr >> 48));
data_.init(intPtr);
data_.setData((uintptr_t(extra) << 48) | ptr);
}
- // Logically private, but we can't have private data members and
- // still be considered a POD. (In C++11 we are still a standard
- // layout struct if this is private, but it doesn't matter, since
- // gcc (4.6) won't let us use this with attribute packed still in
- // that case.)
+ private:
PicoSpinLock<uintptr_t> data_;
-};
+} FOLLY_PACK_ATTR;
+static_assert(
+ std::is_pod<PackedSyncPtr<void>>::value,
+ "PackedSyncPtr must be kept a POD type.");
static_assert(sizeof(PackedSyncPtr<void>) == 8,
"PackedSyncPtr should be only 8 bytes---something is "
"messed up");
+template <typename T>
+std::ostream& operator<<(std::ostream& os, const PackedSyncPtr<T>& ptr) {
+ os << "PackedSyncPtr(" << ptr.get() << ", " << ptr.extra() << ")";
+ return os;
}
-
-#endif
+} // namespace folly