encoding: ensure Buffer is move constructible and assignable

refs #2234

Change-Id: Ic16914eff91bcbae89b6a66c5870a57086d9511a
diff --git a/.waf-tools/type_traits.py b/.waf-tools/type_traits.py
new file mode 100644
index 0000000..a895e07
--- /dev/null
+++ b/.waf-tools/type_traits.py
@@ -0,0 +1,15 @@
+# -*- Mode: python; py-indent-offset: 4; indent-tabs-mode: nil; coding: utf-8; -*-
+
+def checkForTypeProperty(conf, prop, tparams):
+    if conf.check_cxx(msg=('Checking for std::%s' % prop),
+                      fragment=('#include <type_traits>\nstatic_assert(std::%s<%s>::value, "");' %
+                                (prop, tparams)),
+                      features='cxx', mandatory=False):
+        define = 'HAVE_' + prop.upper()
+        conf.define(define, 1)
+        conf.env[define] = True
+
+def configure(conf):
+    checkForTypeProperty(conf, 'is_default_constructible', 'int')
+    checkForTypeProperty(conf, 'is_move_constructible', 'int')
+    checkForTypeProperty(conf, 'is_move_assignable', 'int')
diff --git a/src/encoding/buffer.cpp b/src/encoding/buffer.cpp
new file mode 100644
index 0000000..0402d7d
--- /dev/null
+++ b/src/encoding/buffer.cpp
@@ -0,0 +1,53 @@
+/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
+/**
+ * Copyright (c) 2013-2014 Regents of the University of California.
+ *
+ * This file is part of ndn-cxx library (NDN C++ library with eXperimental eXtensions).
+ *
+ * ndn-cxx library is free software: you can redistribute it and/or modify it under the
+ * terms of the GNU Lesser General Public License as published by the Free Software
+ * Foundation, either version 3 of the License, or (at your option) any later version.
+ *
+ * ndn-cxx library 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 Lesser General Public License for more details.
+ *
+ * You should have received copies of the GNU General Public License and GNU Lesser
+ * General Public License along with ndn-cxx, e.g., in COPYING.md file.  If not, see
+ * <http://www.gnu.org/licenses/>.
+ *
+ * See AUTHORS.md for complete list of ndn-cxx authors and contributors.
+ *
+ * @author Alexander Afanasyev <http://lasr.cs.ucla.edu/afanasyev/index.html>
+ */
+
+#include "buffer.hpp"
+
+namespace ndn {
+
+#if NDN_CXX_HAVE_IS_MOVE_CONSTRUCTIBLE
+static_assert(std::is_move_constructible<Buffer>::value,
+              "Buffer must be MoveConstructible");
+#endif // NDN_CXX_HAVE_IS_MOVE_CONSTRUCTIBLE
+
+#if NDN_CXX_HAVE_IS_MOVE_ASSIGNABLE
+static_assert(std::is_move_assignable<Buffer>::value,
+              "Buffer must be MoveAssignable");
+#endif // NDN_CXX_HAVE_IS_MOVE_ASSIGNABLE
+
+Buffer::Buffer()
+{
+}
+
+Buffer::Buffer(size_t size)
+  : std::vector<uint8_t>(size, 0)
+{
+}
+
+Buffer::Buffer(const void* buf, size_t length)
+  : std::vector<uint8_t>(reinterpret_cast<const uint8_t*>(buf),
+                         reinterpret_cast<const uint8_t*>(buf) + length)
+{
+}
+
+} // namespace ndn
diff --git a/src/encoding/buffer.hpp b/src/encoding/buffer.hpp
index 07591ee..994fbf8 100644
--- a/src/encoding/buffer.hpp
+++ b/src/encoding/buffer.hpp
@@ -44,41 +44,26 @@
 class Buffer : public std::vector<uint8_t>
 {
 public:
-  /**
-   * @brief Creates an empty buffer
+  /** @brief Creates an empty buffer
    */
-  Buffer()
-  {
-  }
+  Buffer();
 
-  /**
-   * @brief Creates a buffer with pre-allocated size
-   * @param size size of the buffer to be allocated
+  /** @brief Creates a buffer with pre-allocated size
+   *  @param size size of the buffer to be allocated
    */
   explicit
-  Buffer(size_t size)
-    : std::vector<uint8_t>(size, 0)
-  {
-  }
+  Buffer(size_t size);
 
-  /**
-   * @brief Create a buffer by copying the supplied data from a const buffer
-   * @param buf const pointer to buffer
-   * @param length length of the buffer to copy
+  /** @brief Create a buffer by copying contents from a buffer
+   *  @param buf const pointer to buffer
+   *  @param length length of the buffer to copy
    */
-  Buffer(const void* buf, size_t length)
-    : std::vector<uint8_t>(reinterpret_cast<const uint8_t*>(buf),
-                           reinterpret_cast<const uint8_t*>(buf) + length)
-  {
-  }
+  Buffer(const void* buf, size_t length);
 
-  /**
-   * @brief Create a buffer by copying the supplied data using iterator interface
-   *
-   * Note that the supplied iterators must be compatible with std::vector<uint8_t> interface
-   *
-   * @param first iterator to a first element to copy
-   * @param last  iterator to an element immediately following the last element to copy
+  /** @brief Create a buffer by copying contents of the range [first, last)
+   *  @tparam InputIterator an InputIterator compatible with std::vector<uint8_t> constructor
+   *  @param first iterator to the first element to copy
+   *  @param last  iterator to the element immediately following the last element to copy
    */
   template <class InputIterator>
   Buffer(InputIterator first, InputIterator last)
@@ -86,8 +71,7 @@
   {
   }
 
-  /**
-   * @brief Get pointer to the first byte of the buffer
+  /** @return pointer to the first byte of the buffer
    */
   uint8_t*
   get()
@@ -95,8 +79,9 @@
     return &front();
   }
 
-  /**
-   * @brief Get pointer to the first byte of the buffer (alternative version)
+  /** @return pointer to the first byte of the buffer
+   *
+   *  This is same as \p .get()
    */
   uint8_t*
   buf()
@@ -104,9 +89,8 @@
     return &front();
   }
 
-  /**
-   * @brief Get pointer to the first byte of the buffer and cast
-   * it (reinterpret_cast) to the requested type T
+  /** @return pointer to the first byte of the buffer and reinterpret_cast
+   *          it to the requested type T
    */
   template<class T>
   T*
@@ -115,8 +99,9 @@
     return reinterpret_cast<T*>(&front());
   }
 
-  /**
-   * @brief Get pointer to the first byte of the buffer (alternative version)
+  /** @return pointer to the first byte of the buffer
+   *
+   *  This is same as \p .get()
    */
   const uint8_t*
   buf() const
@@ -124,8 +109,7 @@
     return &front();
   }
 
-  /**
-   * @brief Get const pointer to the first byte of the buffer
+  /** @return pointer to the first byte of the buffer
    */
   const uint8_t*
   get() const
@@ -133,9 +117,8 @@
     return &front();
   }
 
-  /**
-   * @brief Get const pointer to the first byte of the buffer and cast
-   * it (reinterpret_cast) to the requested type T
+  /** @return const pointer to the first byte of the buffer and reinterpret_cast
+   *          it to the requested type T
    */
   template<class T>
   const T*
@@ -145,6 +128,6 @@
   }
 };
 
-} // ndn
+} // namespace ndn
 
 #endif // NDN_ENCODING_BUFFER_HPP
diff --git a/wscript b/wscript
index 2c62c5e..36cf327 100644
--- a/wscript
+++ b/wscript
@@ -13,7 +13,7 @@
     opt.load(['compiler_cxx', 'gnu_dirs', 'c_osx'])
     opt.load(['default-compiler-flags', 'coverage', 'osx-security', 'pch',
               'boost', 'openssl', 'cryptopp', 'sqlite3',
-              'doxygen', 'sphinx_build'],
+              'doxygen', 'sphinx_build', 'type_traits'],
              tooldir=['.waf-tools'])
 
     opt = opt.add_option_group('Library Options')
@@ -40,7 +40,7 @@
     conf.load(['compiler_cxx', 'gnu_dirs', 'c_osx',
                'default-compiler-flags', 'osx-security', 'pch',
                'boost', 'openssl', 'cryptopp', 'sqlite3',
-               'doxygen', 'sphinx_build'])
+               'doxygen', 'sphinx_build', 'type_traits'])
 
     conf.env['WITH_TESTS'] = conf.options.with_tests
     conf.env['WITH_TOOLS'] = conf.options.with_tools