diff --git a/libraries/AP_HAL/utility/OwnPtr.h b/libraries/AP_HAL/utility/OwnPtr.h
new file mode 100644
index 0000000000..5ca9c54682
--- /dev/null
+++ b/libraries/AP_HAL/utility/OwnPtr.h
@@ -0,0 +1,127 @@
+/// -*- tab-width: 4; Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*-
+/*
+ * Copyright (C) 2015-2016 Intel Corporation. All rights reserved.
+ *
+ * This file is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see .
+ */
+#pragma once
+
+#include
+
+namespace AP_HAL {
+
+/* Poor's man std::unique_ptr
+ *
+ * OwnPtr is a container for a pointer declaring ownership.
+ *
+ * The goal is to allow to own object, pass it around and automatically delete
+ * the pointer when the container goes out of scope.
+ *
+ * In order to pass it around the move constructor or move assignment operator
+ * must be used. operator*, operator-> and the get() method can be used to get
+ * the pointer contained in the OwnPtr container.
+ *
+ * The OwnPtr name comes from similar class in WebKit, before they switched to
+ * std::unique_ptr. The implementation is different/simpler. We need our own
+ * implementation since the header (and thus std::unique_ptr) is not
+ * compatible with the PX4 toolchain and/or nuttx headers.
+ */
+template
+class OwnPtr {
+public:
+ OwnPtr() : _ptr(nullptr) { }
+ OwnPtr(std::nullptr_t) : _ptr(nullptr) { }
+
+ /* non-copyable */
+ OwnPtr(const OwnPtr &other) = delete;
+
+ /* Allow construction from a derived class U */
+ template
+ OwnPtr(OwnPtr&& other) : _ptr(other.leak()) { }
+
+ OwnPtr(T *ptr) : _ptr(ptr) { }
+
+ OwnPtr& operator=(std::nullptr_t) { clear(); return *this; }
+
+ template
+ OwnPtr& operator=(OwnPtr&& other)
+ {
+ T *old = _ptr;
+ _ptr = other.leak();
+ delete old;
+ return *this;
+ }
+
+ template
+ OwnPtr& operator=(U *other)
+ {
+ T *old = _ptr;
+ _ptr = other;
+ delete old;
+ return *this;
+ }
+
+ ~OwnPtr() { delete _ptr; }
+
+ void clear()
+ {
+ delete leak();
+ }
+
+ T *leak()
+ {
+ T *old = _ptr;
+ _ptr = nullptr;
+ return old;
+ }
+
+ T *get() const
+ {
+ return _ptr;
+ }
+
+ T& operator*() const { return *_ptr; }
+ T *operator->() const { return _ptr; }
+ bool operator !() const { return !_ptr; }
+ explicit operator bool() const { return _ptr != nullptr; }
+
+private:
+ T *_ptr;
+};
+
+template
+inline bool operator==(T* a, const OwnPtr& b)
+{
+ return a == b.get();
+}
+
+template
+inline bool operator==(const OwnPtr& a, T* b)
+{
+ return a.get() == b;
+}
+
+template
+inline bool operator!=(T* a, const OwnPtr& b)
+{
+ return a != b.get();
+}
+
+template
+inline bool operator!=(const OwnPtr& a, T* b)
+{
+ return a.get() != b;
+}
+
+}
diff --git a/libraries/AP_HAL/utility/tests/test_own_ptr.cpp b/libraries/AP_HAL/utility/tests/test_own_ptr.cpp
new file mode 100644
index 0000000000..655ef6722e
--- /dev/null
+++ b/libraries/AP_HAL/utility/tests/test_own_ptr.cpp
@@ -0,0 +1,199 @@
+/// -*- tab-width: 4; Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*-
+/*
+ * Copyright (C) 2015-2016 Intel Corporation. All rights reserved.
+ *
+ * This file is free software: you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This file is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ * See the GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program. If not, see .
+ */
+#include
+
+#include
+#include
+
+TEST(OwnPtrTest, SamePointer)
+{
+ int *a = new int{42};
+ AP_HAL::OwnPtr own(a);
+
+ EXPECT_TRUE(own == a);
+ EXPECT_TRUE(a == own);
+
+ EXPECT_FALSE(own != a);
+ EXPECT_FALSE(a != own);
+
+ EXPECT_EQ(a, own.get());
+}
+
+TEST(OwnPtrTest, MoveOwnership)
+{
+ int *a = new int{42};
+ AP_HAL::OwnPtr own(a);
+ AP_HAL::OwnPtr own2 = std::move(own);
+
+ EXPECT_EQ(own2.get(), a);
+ EXPECT_EQ(own.get(), nullptr);
+}
+
+class TestDeleted {
+public:
+ TestDeleted(unsigned int &d) : deleted(d) { }
+ ~TestDeleted() { deleted++; }
+
+ unsigned int &deleted;
+};
+
+TEST(OwnPtrTest, DeleteOutOfScope)
+{
+ unsigned int deleted = 0;
+
+ {
+ AP_HAL::OwnPtr own(new TestDeleted{deleted});
+ }
+
+ EXPECT_EQ(deleted, 1);
+}
+
+TEST(OwnPtrTest, DeleteOutOfScopeAfterMove)
+{
+ unsigned int deleted = 0;
+ AP_HAL::OwnPtr own;
+
+ {
+ AP_HAL::OwnPtr own2(new TestDeleted{deleted});
+ own = std::move(own2);
+ }
+
+ // own2 is now out of scope, but it has been moved already
+ EXPECT_EQ(deleted, 0);
+
+ // now remove also 'own'
+ own.clear();
+
+ EXPECT_EQ(deleted, 1);
+}
+
+class TestCall {
+public:
+ int foo() { return 42; }
+};
+
+TEST(OwnPtrTest, CallMethod)
+{
+ AP_HAL::OwnPtr own(new TestCall{});
+ EXPECT_EQ(own->foo(), 42);
+ EXPECT_EQ((*own).foo(), 42);
+}
+
+class TestDestructor {
+public:
+ TestDestructor(AP_HAL::OwnPtr v) : _v(std::move(v)) { }
+
+ AP_HAL::OwnPtr _v;
+};
+
+TEST(OwnPtrTest, MoveToConstructor)
+{
+ unsigned int deleted = 0;
+
+ AP_HAL::OwnPtr own(new TestDeleted{deleted});
+ {
+ EXPECT_EQ(0, deleted);
+ TestDestructor destructor{std::move(own)};
+ EXPECT_EQ(0, deleted);
+ }
+ EXPECT_EQ(1, deleted);
+}
+
+static AP_HAL::OwnPtr create_test_deleted(unsigned int &deleted)
+{
+ return AP_HAL::OwnPtr(new TestDeleted(deleted));
+}
+
+TEST(OwnPtrTest, ReturnType)
+{
+ unsigned int deleted = 0;
+
+ auto own = create_test_deleted(deleted);
+ EXPECT_EQ(0, deleted);
+ {
+ auto own2 = create_test_deleted(deleted);
+ EXPECT_EQ(0, deleted);
+ }
+ EXPECT_EQ(1, deleted);
+ own.clear();
+ EXPECT_EQ(2, deleted);
+}
+
+TEST(OwnPtrTest, ReplacePointer)
+{
+ unsigned int deleted1 = 0;
+ unsigned int deleted2 = 0;
+
+ auto own = create_test_deleted(deleted1);
+ EXPECT_EQ(0, deleted1);
+ {
+ own = create_test_deleted(deleted2);
+ EXPECT_EQ(1, deleted1);
+ }
+ EXPECT_EQ(0, deleted2);
+ own = nullptr;
+ EXPECT_EQ(1, deleted2);
+}
+
+TEST(OwnPtrTest, ReplaceWithRawPointer)
+{
+ unsigned int deleted1 = 0;
+
+ auto own = create_test_deleted(deleted1);
+ EXPECT_EQ(0, deleted1);
+ {
+ own = new TestDeleted{deleted1};
+ EXPECT_EQ(1, deleted1);
+ }
+}
+
+TEST(OwnPtrTest, Empty)
+{
+ int *a = new int{42};
+
+ AP_HAL::OwnPtr own1;
+ EXPECT_FALSE(own1);
+
+ own1 = a;
+ EXPECT_TRUE((bool) own1);
+}
+
+class A {
+public:
+ A(int a) : _a(a) { }
+ int _a;
+};
+
+class B : public A {
+public:
+ B() : A(42) { }
+};
+
+TEST(OwnPtrTest, Inheritance)
+{
+ A *a = new A(21);
+ B *b = new B();
+ AP_HAL::OwnPtr own_a(a);
+ AP_HAL::OwnPtr own_b(b);
+
+ own_a = std::move(own_b);
+ EXPECT_EQ(b, own_a.get());
+ EXPECT_EQ(42, own_a->_a);
+}
+
+AP_GTEST_MAIN()
diff --git a/libraries/AP_HAL/utility/tests/wscript b/libraries/AP_HAL/utility/tests/wscript
new file mode 100644
index 0000000000..cd3e5e3ce7
--- /dev/null
+++ b/libraries/AP_HAL/utility/tests/wscript
@@ -0,0 +1,7 @@
+#!/usr/bin/env python
+# encoding: utf-8
+
+def build(bld):
+ bld.ap_find_tests(
+ use='ap',
+ )