Browse Source

Moving pointers to own project.

Samuel Jaffe 9 years ago
commit
1d247ec1d0
5 changed files with 425 additions and 0 deletions
  1. 89 0
      maybe_null.hpp
  2. 65 0
      not_null.hpp
  3. 15 0
      pointer_fwd.hpp
  4. 19 0
      pointer_traits.hpp
  5. 237 0
      pointers.xcodeproj/project.pbxproj

+ 89 - 0
maybe_null.hpp

@@ -0,0 +1,89 @@
+//
+//  maybe_null.hpp
+//  pointer
+//
+//  Created by Sam Jaffe on 9/24/15.
+//
+//
+
+#pragma once
+
+#include <stdexcept>
+#include <memory>
+
+#include "pointer_fwd.hpp"
+
+#include "pointer_traits.hpp"
+#include "not_null.hpp"
+
+class unchecked_pointer_exception : public std::logic_error {
+  using std::logic_error::logic_error;
+};
+
+template <typename P> class maybe_null<not_null<P>>; // not permitted
+
+template <typename T>
+class maybe_null {
+public:
+  using element_type = typename detail::pointer_traits<T>::element_type;
+  using pointer = typename detail::pointer_traits<T>::pointer;
+  using reference = typename detail::pointer_traits<T>::reference;
+  
+  maybe_null() : _ptr(nullptr) {}
+  template <typename... Args> maybe_null(Args && ...args) : _ptr(std::forward<Args>(args)...) { }
+  maybe_null(maybe_null const&) = default;
+  template <typename Y> maybe_null(maybe_null<Y> const& other) : _ptr(other.ptr_) { }
+  template <typename Y> maybe_null(not_null<Y> const& other) : _ptr(other.get()) { }
+  
+  maybe_null& operator=(T ptr) { return operator=(maybe_null<T>(ptr)); }
+  maybe_null& operator=(maybe_null const&) = default;
+  template <typename Y> maybe_null& operator=(maybe_null<Y> const&other) {
+    if (_ptr != other.get()) {
+      _ptr = other.get();
+#if defined( DEBUG )
+      tested_ = other.tested_;
+#endif
+    }
+    return *this;
+  }
+  
+  template <typename Y> maybe_null& operator=(not_null<Y> const&other) {
+    _ptr = other.get();
+#if defined( DEBUG )
+    tested_ = true;
+#endif
+    return *this;
+  }
+  
+  
+  operator bool() const {
+#if defined( DEBUG )
+    tested_ = true;
+#endif
+    return bool(_ptr);
+  }
+  
+  pointer get() const {
+#if defined( DEBUG )
+    if ( !tested_ ) {
+      throw unchecked_pointer_exception{"did not verify that pointer was non-null"};
+    }
+#endif
+    return std::addressof(operator*());
+  }
+  //  operator T() const { return get(); }
+  pointer operator->() const { return get(); }
+  reference operator*() const { return *_ptr; }
+  
+  bool operator==(maybe_null const&rhs) const { return _ptr == rhs._ptr; }
+  bool operator!=(maybe_null const&rhs) const { return _ptr != rhs._ptr; }
+  bool operator<=(maybe_null const&rhs) const { return _ptr <= rhs._ptr; }
+  bool operator>=(maybe_null const&rhs) const { return _ptr >= rhs._ptr; }
+  bool operator< (maybe_null const&rhs) const { return _ptr <  rhs._ptr; }
+  bool operator> (maybe_null const&rhs) const { return _ptr >  rhs._ptr; }
+private:
+  T _ptr;
+#if defined( DEBUG )
+  mutable bool tested_ = false;
+#endif
+};

+ 65 - 0
not_null.hpp

@@ -0,0 +1,65 @@
+//
+//  not_null.hpp
+//  pointer
+//
+//  Created by Sam Jaffe on 9/24/15.
+//
+//
+
+#pragma once
+
+#include <stdexcept>
+#include <memory>
+
+#include "pointer_fwd.hpp"
+
+#include "pointer_traits.hpp"
+
+class null_pointer_exception : public std::invalid_argument {
+  using std::invalid_argument::invalid_argument;
+};
+
+template <typename P> class not_null<std::weak_ptr<P>>; // A weak_ptr cannot be a not_null
+
+template <typename T>
+class not_null {
+public:
+  using element_type = typename detail::pointer_traits<T>::element_type;
+  using pointer = typename detail::pointer_traits<T>::pointer;
+  using reference = typename detail::pointer_traits<T>::reference;
+  
+  explicit not_null(std::nullptr_t) = delete;
+  explicit not_null(int) = delete;
+  not_null(T p) : _ptr(p) { validate(); }
+  not_null(not_null const&) = default;
+  template <typename Y> not_null(not_null<Y> const& other) : _ptr(other.get()) { }
+  
+  not_null& operator=(std::nullptr_t) = delete;
+  not_null& operator=(int) = delete;
+  not_null& operator=(T ptr) { return operator=(not_null<T>(ptr)); }
+  not_null& operator=(not_null const&) = default;
+  template <typename Y> not_null& operator=(not_null<Y> const&other) {
+    _ptr = other.get();
+    return *this;
+  }
+  
+  operator bool() const { return true; }
+  
+  pointer get() const { return std::addressof(operator*()); }
+  reference operator*() const { return *_ptr; }
+  pointer operator->() const { return get(); }
+  
+  bool operator==(not_null const&rhs) const { return _ptr == rhs._ptr; }
+  bool operator!=(not_null const&rhs) const { return _ptr != rhs._ptr; }
+  bool operator<=(not_null const&rhs) const { return _ptr <= rhs._ptr; }
+  bool operator>=(not_null const&rhs) const { return _ptr >= rhs._ptr; }
+  bool operator< (not_null const&rhs) const { return _ptr <  rhs._ptr; }
+  bool operator> (not_null const&rhs) const { return _ptr >  rhs._ptr; }
+private:
+  void validate() {
+    if (get() == nullptr) {
+      throw null_pointer_exception{"not_null<T> cannot be null"};
+    }
+  }
+  T _ptr;
+};

+ 15 - 0
pointer_fwd.hpp

@@ -0,0 +1,15 @@
+//
+//  pointer_fwd.hpp
+//  memory
+//
+//  Created by Sam Jaffe on 8/8/16.
+//
+
+#pragma once
+
+template <typename> class not_null;
+template <typename> class maybe_null;
+template <typename> class owner;
+
+class unchecked_pointer_exception;
+class null_pointer_exception;

+ 19 - 0
pointer_traits.hpp

@@ -0,0 +1,19 @@
+//
+//  pointer_traits.hpp
+//  memory
+//
+//  Created by Sam Jaffe on 7/29/16.
+//
+
+#pragma once
+
+#include <type_traits>
+
+namespace detail {
+  template <typename T>
+  struct pointer_traits {
+    using element_type = typename std::remove_reference<decltype(*std::declval<T>())>::type;
+    using pointer = element_type *;
+    using reference = typename std::add_lvalue_reference<element_type>::type;
+  };
+}

+ 237 - 0
pointers.xcodeproj/project.pbxproj

@@ -0,0 +1,237 @@
+// !$*UTF8*$!
+{
+	archiveVersion = 1;
+	classes = {
+	};
+	objectVersion = 46;
+	objects = {
+
+/* Begin PBXCopyFilesBuildPhase section */
+		CD3DA3F01D9B42BC001B53A0 /* CopyFiles */ = {
+			isa = PBXCopyFilesBuildPhase;
+			buildActionMask = 2147483647;
+			dstPath = /usr/share/man/man1/;
+			dstSubfolderSpec = 0;
+			files = (
+			);
+			runOnlyForDeploymentPostprocessing = 1;
+		};
+/* End PBXCopyFilesBuildPhase section */
+
+/* Begin PBXFileReference section */
+		CD3DA3F21D9B42BC001B53A0 /* pointers_tc */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = pointers_tc; sourceTree = BUILT_PRODUCTS_DIR; };
+		CD3DA3FC1D9B42DE001B53A0 /* pointer_fwd.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = pointer_fwd.hpp; sourceTree = "<group>"; };
+		CD3DA3FD1D9B42DE001B53A0 /* pointer_traits.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = pointer_traits.hpp; sourceTree = "<group>"; };
+		CD3DA3FE1D9B42DE001B53A0 /* maybe_null.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = maybe_null.hpp; sourceTree = "<group>"; };
+		CD3DA3FF1D9B42DE001B53A0 /* not_null.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = not_null.hpp; sourceTree = "<group>"; };
+/* End PBXFileReference section */
+
+/* Begin PBXFrameworksBuildPhase section */
+		CD3DA3EF1D9B42BC001B53A0 /* Frameworks */ = {
+			isa = PBXFrameworksBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXFrameworksBuildPhase section */
+
+/* Begin PBXGroup section */
+		CD3DA3E91D9B42BC001B53A0 = {
+			isa = PBXGroup;
+			children = (
+				CD3DA3FC1D9B42DE001B53A0 /* pointer_fwd.hpp */,
+				CD3DA3FD1D9B42DE001B53A0 /* pointer_traits.hpp */,
+				CD3DA3FE1D9B42DE001B53A0 /* maybe_null.hpp */,
+				CD3DA3FF1D9B42DE001B53A0 /* not_null.hpp */,
+				CD3DA3F31D9B42BC001B53A0 /* Products */,
+			);
+			sourceTree = "<group>";
+		};
+		CD3DA3F31D9B42BC001B53A0 /* Products */ = {
+			isa = PBXGroup;
+			children = (
+				CD3DA3F21D9B42BC001B53A0 /* pointers_tc */,
+			);
+			name = Products;
+			sourceTree = "<group>";
+		};
+/* End PBXGroup section */
+
+/* Begin PBXNativeTarget section */
+		CD3DA3F11D9B42BC001B53A0 /* pointers_tc */ = {
+			isa = PBXNativeTarget;
+			buildConfigurationList = CD3DA3F91D9B42BC001B53A0 /* Build configuration list for PBXNativeTarget "pointers_tc" */;
+			buildPhases = (
+				CD3DA3EE1D9B42BC001B53A0 /* Sources */,
+				CD3DA3EF1D9B42BC001B53A0 /* Frameworks */,
+				CD3DA3F01D9B42BC001B53A0 /* CopyFiles */,
+			);
+			buildRules = (
+			);
+			dependencies = (
+			);
+			name = pointers_tc;
+			productName = pointers;
+			productReference = CD3DA3F21D9B42BC001B53A0 /* pointers_tc */;
+			productType = "com.apple.product-type.tool";
+		};
+/* End PBXNativeTarget section */
+
+/* Begin PBXProject section */
+		CD3DA3EA1D9B42BC001B53A0 /* Project object */ = {
+			isa = PBXProject;
+			attributes = {
+				LastUpgradeCheck = 0720;
+				ORGANIZATIONNAME = "Sam Jaffe";
+				TargetAttributes = {
+					CD3DA3F11D9B42BC001B53A0 = {
+						CreatedOnToolsVersion = 7.2.1;
+					};
+				};
+			};
+			buildConfigurationList = CD3DA3ED1D9B42BC001B53A0 /* Build configuration list for PBXProject "pointers" */;
+			compatibilityVersion = "Xcode 3.2";
+			developmentRegion = English;
+			hasScannedForEncodings = 0;
+			knownRegions = (
+				en,
+			);
+			mainGroup = CD3DA3E91D9B42BC001B53A0;
+			productRefGroup = CD3DA3F31D9B42BC001B53A0 /* Products */;
+			projectDirPath = "";
+			projectRoot = "";
+			targets = (
+				CD3DA3F11D9B42BC001B53A0 /* pointers_tc */,
+			);
+		};
+/* End PBXProject section */
+
+/* Begin PBXSourcesBuildPhase section */
+		CD3DA3EE1D9B42BC001B53A0 /* Sources */ = {
+			isa = PBXSourcesBuildPhase;
+			buildActionMask = 2147483647;
+			files = (
+			);
+			runOnlyForDeploymentPostprocessing = 0;
+		};
+/* End PBXSourcesBuildPhase section */
+
+/* Begin XCBuildConfiguration section */
+		CD3DA3F71D9B42BC001B53A0 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+				CLANG_CXX_LIBRARY = "libc++";
+				CLANG_ENABLE_MODULES = YES;
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				CLANG_WARN_UNREACHABLE_CODE = YES;
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+				CODE_SIGN_IDENTITY = "-";
+				COPY_PHASE_STRIP = NO;
+				DEBUG_INFORMATION_FORMAT = dwarf;
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
+				ENABLE_TESTABILITY = YES;
+				GCC_C_LANGUAGE_STANDARD = gnu99;
+				GCC_DYNAMIC_NO_PIC = NO;
+				GCC_NO_COMMON_BLOCKS = YES;
+				GCC_OPTIMIZATION_LEVEL = 0;
+				GCC_PREPROCESSOR_DEFINITIONS = (
+					"DEBUG=1",
+					"$(inherited)",
+				);
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+				GCC_WARN_UNUSED_FUNCTION = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				MACOSX_DEPLOYMENT_TARGET = 10.10;
+				MTL_ENABLE_DEBUG_INFO = YES;
+				ONLY_ACTIVE_ARCH = YES;
+				SDKROOT = macosx;
+			};
+			name = Debug;
+		};
+		CD3DA3F81D9B42BC001B53A0 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				ALWAYS_SEARCH_USER_PATHS = NO;
+				CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
+				CLANG_CXX_LIBRARY = "libc++";
+				CLANG_ENABLE_MODULES = YES;
+				CLANG_ENABLE_OBJC_ARC = YES;
+				CLANG_WARN_BOOL_CONVERSION = YES;
+				CLANG_WARN_CONSTANT_CONVERSION = YES;
+				CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
+				CLANG_WARN_EMPTY_BODY = YES;
+				CLANG_WARN_ENUM_CONVERSION = YES;
+				CLANG_WARN_INT_CONVERSION = YES;
+				CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
+				CLANG_WARN_UNREACHABLE_CODE = YES;
+				CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
+				CODE_SIGN_IDENTITY = "-";
+				COPY_PHASE_STRIP = NO;
+				DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
+				ENABLE_NS_ASSERTIONS = NO;
+				ENABLE_STRICT_OBJC_MSGSEND = YES;
+				GCC_C_LANGUAGE_STANDARD = gnu99;
+				GCC_NO_COMMON_BLOCKS = YES;
+				GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
+				GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
+				GCC_WARN_UNDECLARED_SELECTOR = YES;
+				GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
+				GCC_WARN_UNUSED_FUNCTION = YES;
+				GCC_WARN_UNUSED_VARIABLE = YES;
+				MACOSX_DEPLOYMENT_TARGET = 10.10;
+				MTL_ENABLE_DEBUG_INFO = NO;
+				SDKROOT = macosx;
+			};
+			name = Release;
+		};
+		CD3DA3FA1D9B42BC001B53A0 /* Debug */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = "$(TARGET_NAME)";
+			};
+			name = Debug;
+		};
+		CD3DA3FB1D9B42BC001B53A0 /* Release */ = {
+			isa = XCBuildConfiguration;
+			buildSettings = {
+				PRODUCT_NAME = "$(TARGET_NAME)";
+			};
+			name = Release;
+		};
+/* End XCBuildConfiguration section */
+
+/* Begin XCConfigurationList section */
+		CD3DA3ED1D9B42BC001B53A0 /* Build configuration list for PBXProject "pointers" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				CD3DA3F71D9B42BC001B53A0 /* Debug */,
+				CD3DA3F81D9B42BC001B53A0 /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+			defaultConfigurationName = Release;
+		};
+		CD3DA3F91D9B42BC001B53A0 /* Build configuration list for PBXNativeTarget "pointers_tc" */ = {
+			isa = XCConfigurationList;
+			buildConfigurations = (
+				CD3DA3FA1D9B42BC001B53A0 /* Debug */,
+				CD3DA3FB1D9B42BC001B53A0 /* Release */,
+			);
+			defaultConfigurationIsVisible = 0;
+		};
+/* End XCConfigurationList section */
+	};
+	rootObject = CD3DA3EA1D9B42BC001B53A0 /* Project object */;
+}