{"action":"created","comment":{"url":"https://api.github.com/repos/ros2/rosidl/pulls/comments/68330364","id":68330364,"diff_hunk":"@@ -0,0 +1,712 @@\n+// Copyright 2016 Open Source Robotics Foundation, Inc.\n+//\n+// Licensed under the Apache License, Version 2.0 (the \"License\");\n+// you may not use this file except in compliance with the License.\n+// You may obtain a copy of the License at\n+//\n+//     http://www.apache.org/licenses/LICENSE-2.0\n+//\n+// Unless required by applicable law or agreed to in writing, software\n+// distributed under the License is distributed on an \"AS IS\" BASIS,\n+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n+// See the License for the specific language governing permissions and\n+// limitations under the License.\n+\n+#ifndef ROSIDL_GENERATOR_CPP__BOUNDED_VECTOR_HPP_\n+#define ROSIDL_GENERATOR_CPP__BOUNDED_VECTOR_HPP_\n+\n+#include <algorithm>\n+#include <memory>\n+#include <stdexcept>\n+#include <utility>\n+#include <vector>\n+\n+namespace rosidl_generator_cpp\n+{\n+\n+/**\n+ *  @brief  A container based on std::vector but with an upper bound.\n+ *\n+ *  @tparam  _Tp  Type of element.\n+ *  @tparam  _UpperBound  The upper bound for the number of elements.\n+ *  @tparam  _Alloc  Allocator type, defaults to allocator<_Tp>.\n+ *\n+ *  Meets the same requirements as std::vector.\n+*/\n+template<typename _Tp, std::size_t _UpperBound, typename _Alloc = std::allocator<_Tp>>\n+class BoundedVector\n+  : protected std::vector<_Tp, _Alloc>\n+{\n+  using _Base = std::vector<_Tp, _Alloc>;\n+\n+public:\n+  using typename _Base::value_type;\n+  using typename _Base::pointer;\n+  using typename _Base::const_pointer;\n+  using typename _Base::reference;\n+  using typename _Base::const_reference;\n+  using typename _Base::iterator;\n+  using typename _Base::const_iterator;\n+  using typename _Base::const_reverse_iterator;\n+  using typename _Base::reverse_iterator;\n+  using typename _Base::size_type;\n+  using typename _Base::difference_type;\n+  using typename _Base::allocator_type;\n+\n+  /**\n+   *  @brief  Creates a %BoundedVector with no elements.\n+   */\n+  BoundedVector()\n+  noexcept(std::is_nothrow_default_constructible<_Alloc>::value)\n+  : _Base()\n+  {}\n+\n+  /**\n+   *  @brief  Creates a %BoundedVector with no elements.\n+   *  @param  __a  An allocator object.\n+   */\n+  explicit\n+  BoundedVector(\n+    const typename _Base::allocator_type & __a)\n+  noexcept\n+  : _Base(__a)\n+  {}\n+\n+  /**\n+   *  @brief  Creates a %BoundedVector with default constructed elements.\n+   *  @param  __n  The number of elements to initially create.\n+   *  @param  __a  An allocator.\n+   *\n+   *  This constructor fills the %BoundedVector with @a __n default\n+   *  constructed elements.\n+   */\n+  explicit\n+  BoundedVector(\n+    typename _Base::size_type __n,\n+    const typename _Base::allocator_type & __a = allocator_type())\n+  : _Base(__n, __a)\n+  {\n+    if (__n > _UpperBound) {\n+      throw std::length_error(\"Exceeded upper bound\");\n+    }\n+  }\n+\n+  /**\n+   *  @brief  Creates a %BoundedVector with copies of an exemplar element.\n+   *  @param  __n  The number of elements to initially create.\n+   *  @param  __value  An element to copy.\n+   *  @param  __a  An allocator.\n+   *\n+   *  This constructor fills the %BoundedVector with @a __n copies of @a __value.\n+   */\n+  BoundedVector(\n+    typename _Base::size_type __n,\n+    const typename _Base::value_type & __value,\n+    const typename _Base::allocator_type & __a = allocator_type())\n+  : _Base(__n, __value, __a)\n+  {\n+    if (__n > _UpperBound) {\n+      throw std::length_error(\"Exceeded upper bound\");\n+    }\n+  }\n+\n+  /**\n+   *  @brief  %BoundedVector copy constructor.\n+   *  @param  __x  A %BoundedVector of identical element and allocator types.\n+   *\n+   *  The newly-created %BoundedVector uses a copy of the allocation\n+   *  object used by @a __x.  All the elements of @a __x are copied,\n+   *  but any extra memory in\n+   *  @a __x (for fast expansion) will not be copied.\n+   */\n+  BoundedVector(\n+    const BoundedVector & __x)\n+  : _Base(__x)\n+  {}\n+\n+  /**\n+   *  @brief  %BoundedVector move constructor.\n+   *  @param  __x  A %BoundedVector of identical element and allocator types.\n+   *\n+   *  The newly-created %BoundedVector contains the exact contents of @a __x.\n+   *  The contents of @a __x are a valid, but unspecified %BoundedVector.\n+   */\n+  BoundedVector(BoundedVector && __x) noexcept\n+  : _Base(std::move(__x))\n+  {}\n+\n+  /// Copy constructor with alternative allocator\n+  BoundedVector(const BoundedVector & __x, const typename _Base::allocator_type & __a)\n+  : _Base(__x, __a)\n+  {}\n+\n+  /**\n+   *  @brief  Builds a %BoundedVector from an initializer list.\n+   *  @param  __l  An initializer_list.\n+   *  @param  __a  An allocator.\n+   *\n+   *  Create a %BoundedVector consisting of copies of the elements in the\n+   *  initializer_list @a __l.\n+   *\n+   *  This will call the element type's copy constructor N times\n+   *  (where N is @a __l.size()) and do no memory reallocation.\n+   */\n+  BoundedVector(\n+    std::initializer_list<typename _Base::value_type> __l,\n+    const typename _Base::allocator_type & __a = typename _Base::allocator_type())\n+  : _Base(__l, __a)\n+  {\n+    if (__l.size() > _UpperBound) {\n+      throw std::length_error(\"Exceeded upper bound\");\n+    }\n+  }\n+\n+  /**\n+   *  @brief  Builds a %BoundedVector from a range.\n+   *  @param  __first  An input iterator.\n+   *  @param  __last  An input iterator.\n+   *  @param  __a  An allocator.\n+   *\n+   *  Create a %BoundedVector consisting of copies of the elements from\n+   *  [first,last).\n+   *\n+   *  If the iterators are forward, bidirectional, or\n+   *  random-access, then this will call the elements' copy\n+   *  constructor N times (where N is distance(first,last)) and do\n+   *  no memory reallocation.  But if only input iterators are\n+   *  used, then this will do at most 2N calls to the copy\n+   *  constructor, and logN memory reallocations.\n+   */\n+  template<\n+    typename _InputIterator\n+  >\n+  BoundedVector(\n+    _InputIterator __first,\n+    _InputIterator __last,\n+    const typename _Base::allocator_type & __a = allocator_type())\n+  : _Base(__first, __last, __a)\n+  {\n+    if (size() > _UpperBound) {\n+      throw std::length_error(\"Exceeded upper bound\");\n+    }\n+  }\n+\n+  /**\n+   *  The dtor only erases the elements, and note that if the\n+   *  elements themselves are pointers, the pointed-to memory is\n+   *  not touched in any way.  Managing the pointer is the user's\n+   *  responsibility.\n+   */\n+  ~BoundedVector() noexcept\n+  {}\n+\n+  /**\n+   *  @brief  %BoundedVector assignment operator.\n+   *  @param  __x  A %BoundedVector of identical element and allocator types.\n+   *\n+   *  All the elements of @a __x are copied, but any extra memory in\n+   *  @a __x (for fast expansion) will not be copied.  Unlike the\n+   *  copy constructor, the allocator object is not copied.\n+   */\n+  BoundedVector &\n+  operator=(const BoundedVector & __x)\n+  {\n+    reinterpret_cast<std::vector<_Tp, _Alloc> *>(this)->operator=(\n+      *reinterpret_cast<const std::vector<_Tp, _Alloc> *>(&__x));\n+    return *this;\n+  }\n+\n+  /**\n+   *  @brief  %BoundedVector list assignment operator.\n+   *  @param  __l  An initializer_list.\n+   *\n+   *  This function fills a %BoundedVector with copies of the elements in the\n+   *  initializer list @a __l.\n+   *\n+   *  Note that the assignment completely changes the %BoundedVector and\n+   *  that the resulting %BoundedVector's size is the same as the number\n+   *  of elements assigned.  Old data may be lost.\n+   */\n+  BoundedVector &\n+  operator=(std::initializer_list<typename _Base::value_type> __l)\n+  {\n+    if (__l.size() > _UpperBound) {\n+      throw std::length_error(\"Exceeded upper bound\");\n+    }\n+    _Base::operator=(__l);\n+    return *this;\n+  }\n+\n+  /**\n+   *  @brief  Assigns a given value to a %BoundedVector.\n+   *  @param  __n  Number of elements to be assigned.\n+   *  @param  __val  Value to be assigned.\n+   *\n+   *  This function fills a %BoundedVector with @a __n copies of the given\n+   *  value.  Note that the assignment completely changes the\n+   *  %BoundedVector and that the resulting %BoundedVector's size is the same as\n+   *  the number of elements assigned.  Old data may be lost.\n+   */\n+  void\n+  assign(\n+    typename _Base::size_type __n,\n+    const typename _Base::value_type & __val)\n+  {\n+    if (__n > _UpperBound) {\n+      throw std::length_error(\"Exceeded upper bound\");\n+    }\n+    _Base::assign(__n, __val);\n+  }\n+\n+  /**\n+   *  @brief  Assigns a range to a %BoundedVector.\n+   *  @param  __first  An input iterator.\n+   *  @param  __last   An input iterator.\n+   *\n+   *  This function fills a %BoundedVector with copies of the elements in the\n+   *  range [__first,__last).\n+   *\n+   *  Note that the assignment completely changes the %BoundedVector and\n+   *  that the resulting %BoundedVector's size is the same as the number\n+   *  of elements assigned.  Old data may be lost.\n+   */\n+  template<\n+    typename _InputIterator\n+  >\n+  void\n+  assign(_InputIterator __first, _InputIterator __last)\n+  {\n+    if (size() + std::distance(__first, __last) > _UpperBound) {\n+      throw std::length_error(\"Exceeded upper bound\");\n+    }\n+    _Base::assign(__first, __last);\n+  }\n+\n+  /**\n+   *  @brief  Assigns an initializer list to a %BoundedVector.\n+   *  @param  __l  An initializer_list.\n+   *\n+   *  This function fills a %BoundedVector with copies of the elements in the\n+   *  initializer list @a __l.\n+   *\n+   *  Note that the assignment completely changes the %BoundedVector and\n+   *  that the resulting %BoundedVector's size is the same as the number\n+   *  of elements assigned.  Old data may be lost.\n+   */\n+  void\n+  assign(std::initializer_list<typename _Base::value_type> __l)\n+  {\n+    if (__l.size() > _UpperBound) {\n+      throw std::length_error(\"Exceeded upper bound\");\n+    }\n+    _Base::assign(__l);\n+  }\n+\n+  using _Base::begin;\n+  using _Base::end;\n+  using _Base::rbegin;\n+  using _Base::rend;\n+  using _Base::cbegin;\n+  using _Base::cend;\n+  using _Base::crbegin;\n+  using _Base::crend;\n+  using _Base::size;\n+\n+  /**  Returns the size() of the largest possible %BoundedVector.  */\n+  typename _Base::size_type\n+  max_size() const noexcept\n+  {\n+    return std::min(_UpperBound, _Base::max_size());\n+  }\n+\n+  /**\n+   *  @brief  Resizes the %BoundedVector to the specified number of elements.\n+   *  @param  __new_size  Number of elements the %BoundedVector should contain.\n+   *\n+   *  This function will %resize the %BoundedVector to the specified\n+   *  number of elements.  If the number is smaller than the\n+   *  %BoundedVector's current size the %BoundedVector is truncated, otherwise\n+   *  default constructed elements are appended.\n+   */\n+  void\n+  resize(typename _Base::size_type __new_size)\n+  {\n+    if (__new_size > _UpperBound) {\n+      throw std::length_error(\"Exceeded upper bound\");\n+    }\n+    _Base::resize(__new_size);\n+  }\n+\n+  /**\n+   *  @brief  Resizes the %BoundedVector to the specified number of elements.\n+   *  @param  __new_size  Number of elements the %BoundedVector should contain.\n+   *  @param  __x  Data with which new elements should be populated.\n+   *\n+   *  This function will %resize the %BoundedVector to the specified\n+   *  number of elements.  If the number is smaller than the\n+   *  %BoundedVector's current size the %BoundedVector is truncated, otherwise\n+   *  the %BoundedVector is extended and new elements are populated with\n+   *  given data.\n+   */\n+  void\n+  resize(\n+    typename _Base::size_type __new_size,\n+    const typename _Base::value_type & __x)\n+  {\n+    if (__new_size > _UpperBound) {\n+      throw std::length_error(\"Exceeded upper bound\");\n+    }\n+    _Base::resize(__new_size, __x);\n+  }\n+\n+  using _Base::shrink_to_fit;\n+  using _Base::capacity;\n+  using _Base::empty;\n+\n+  /**\n+   *  @brief  Attempt to preallocate enough memory for specified number of\n+   *          elements.\n+   *  @param  __n  Number of elements required.\n+   *  @throw  std::length_error  If @a n exceeds @c max_size().\n+   *\n+   *  This function attempts to reserve enough memory for the\n+   *  %BoundedVector to hold the specified number of elements.  If the\n+   *  number requested is more than max_size(), length_error is\n+   *  thrown.\n+   *\n+   *  The advantage of this function is that if optimal code is a\n+   *  necessity and the user can determine the number of elements\n+   *  that will be required, the user can reserve the memory in\n+   *  %advance, and thus prevent a possible reallocation of memory\n+   *  and copying of %BoundedVector data.\n+   */\n+  void\n+  reserve(typename _Base::size_type __n)\n+  {\n+    if (__n > _UpperBound) {\n+      throw std::length_error(\"Exceeded upper bound\");\n+    }\n+    _Base::reserve(__n);\n+  }\n+\n+  using _Base::operator[];\n+  using _Base::at;\n+  using _Base::front;\n+  using _Base::back;\n+\n+  // DR 464. Suggestion for new member functions in standard containers.\n+  // data access\n+  /**\n+   *  Returns a pointer such that [data(), data() + size()) is a valid\n+   *  range.  For a non-empty %BoundedVector, data() == &front().\n+   */\n+  template<\n+    typename T,\n+    typename std::enable_if<\n+      !std::is_same<T, _Tp>::value &&\n+      !std::is_same<T, bool>::value\n+    >::type * = nullptr\n+  >\n+  T *\n+  data() noexcept\n+  {\n+    return _Base::data();\n+  }\n+\n+  template<\n+    typename T,\n+    typename std::enable_if<\n+      !std::is_same<T, _Tp>::value &&\n+      !std::is_same<T, bool>::value\n+    >::type * = nullptr\n+  >\n+  const T *\n+  data() const noexcept\n+  {\n+    return _Base::data();\n+  }\n+\n+  // [23.2.4.3] modifiers\n+  /**\n+   *  @brief  Add data to the end of the %BoundedVector.\n+   *  @param  __x  Data to be added.\n+   *\n+   *  This is a typical stack operation.  The function creates an\n+   *  element at the end of the %BoundedVector and assigns the given data\n+   *  to it.  Due to the nature of a %BoundedVector this operation can be\n+   *  done in constant time if the %BoundedVector has preallocated space\n+   *  available.\n+   */\n+  void\n+  push_back(const typename _Base::value_type & __x)\n+  {\n+    if (size() >= _UpperBound) {\n+      throw std::length_error(\"Exceeded upper bound\");\n+    }\n+    _Base::push_back(__x);\n+  }\n+\n+  void\n+  push_back(typename _Base::value_type && __x)\n+  {\n+    if (size() >= _UpperBound) {\n+      throw std::length_error(\"Exceeded upper bound\");\n+    }\n+    _Base::push_back(__x);\n+  }\n+\n+  /**\n+   *  @brief  Inserts an object in %BoundedVector before specified iterator.\n+   *  @param  __position  A const_iterator into the %BoundedVector.\n+   *  @param  __args  Arguments.\n+   *  @return  An iterator that points to the inserted data.\n+   *\n+   *  This function will insert an object of type T constructed\n+   *  with T(std::forward<Args>(args)...) before the specified location.\n+   *  Note that this kind of operation could be expensive for a %BoundedVector\n+   *  and if it is frequently used the user should consider using\n+   *  std::list.\n+   */\n+  template<typename ... _Args>\n+  typename _Base::iterator\n+  emplace(\n+    typename _Base::const_iterator __position,\n+    _Args && ... __args)\n+  {\n+    if (size() >= _UpperBound) {\n+      throw std::length_error(\"Exceeded upper bound\");\n+    }\n+    _Base::emplace(__position, std::forward<_Args>(__args) ...);\n+  }\n+\n+  /**\n+   *  @brief  Inserts given value into %BoundedVector before specified iterator.\n+   *  @param  __position  A const_iterator into the %BoundedVector.\n+   *  @param  __x  Data to be inserted.\n+   *  @return  An iterator that points to the inserted data.\n+   *\n+   *  This function will insert a copy of the given value before\n+   *  the specified location.  Note that this kind of operation\n+   *  could be expensive for a %BoundedVector and if it is frequently\n+   *  used the user should consider using std::list.\n+   */\n+  typename _Base::iterator\n+  insert(\n+    typename _Base::const_iterator __position,\n+    const typename _Base::value_type & __x)\n+  {\n+    if (size() >= _UpperBound) {\n+      throw std::length_error(\"Exceeded upper bound\");\n+    }\n+    return _Base::insert(__position, __x);\n+  }\n+\n+  /**\n+   *  @brief  Inserts given rvalue into %BoundedVector before specified iterator.\n+   *  @param  __position  A const_iterator into the %BoundedVector.\n+   *  @param  __x  Data to be inserted.\n+   *  @return  An iterator that points to the inserted data.\n+   *\n+   *  This function will insert a copy of the given rvalue before\n+   *  the specified location.  Note that this kind of operation\n+   *  could be expensive for a %BoundedVector and if it is frequently\n+   *  used the user should consider using std::list.\n+   */\n+  typename _Base::iterator\n+  insert(\n+    typename _Base::const_iterator __position,\n+    typename _Base::value_type && __x)\n+  {\n+    if (size() >= _UpperBound) {\n+      throw std::length_error(\"Exceeded upper bound\");\n+    }\n+    return _Base::insert(__position, __x);\n+  }\n+\n+  /**\n+   *  @brief  Inserts an initializer_list into the %BoundedVector.\n+   *  @param  __position  An iterator into the %BoundedVector.\n+   *  @param  __l  An initializer_list.\n+   *\n+   *  This function will insert copies of the data in the\n+   *  initializer_list @a l into the %BoundedVector before the location\n+   *  specified by @a position.\n+   *\n+   *  Note that this kind of operation could be expensive for a\n+   *  %BoundedVector and if it is frequently used the user should\n+   *  consider using std::list.\n+   */\n+  typename _Base::iterator\n+  insert(\n+    typename _Base::const_iterator __position,\n+    std::initializer_list<typename _Base::value_type> __l)\n+  {\n+    if (size() + __l.size() > _UpperBound) {\n+      throw std::length_error(\"Exceeded upper bound\");\n+    }\n+    return _Base::insert(__position, __l);\n+  }\n+\n+  /**\n+   *  @brief  Inserts a number of copies of given data into the %BoundedVector.\n+   *  @param  __position  A const_iterator into the %BoundedVector.\n+   *  @param  __n  Number of elements to be inserted.\n+   *  @param  __x  Data to be inserted.\n+   *  @return  An iterator that points to the inserted data.\n+   *\n+   *  This function will insert a specified number of copies of\n+   *  the given data before the location specified by @a position.\n+   *\n+   *  Note that this kind of operation could be expensive for a\n+   *  %BoundedVector and if it is frequently used the user should\n+   *  consider using std::list.\n+   */\n+  typename _Base::iterator\n+  insert(\n+    typename _Base::const_iterator __position,\n+    typename _Base::size_type __n,\n+    const typename _Base::value_type & __x)\n+  {\n+    if (size() + __n > _UpperBound) {\n+      throw std::length_error(\"Exceeded upper bound\");\n+    }\n+    return _Base::insert(__position, __n, __x);\n+  }\n+\n+  /**\n+   *  @brief  Inserts a range into the %BoundedVector.\n+   *  @param  __position  A const_iterator into the %BoundedVector.\n+   *  @param  __first  An input iterator.\n+   *  @param  __last   An input iterator.\n+   *  @return  An iterator that points to the inserted data.\n+   *\n+   *  This function will insert copies of the data in the range\n+   *  [__first,__last) into the %BoundedVector before the location specified\n+   *  by @a pos.\n+   *\n+   *  Note that this kind of operation could be expensive for a\n+   *  %BoundedVector and if it is frequently used the user should\n+   *  consider using std::list.\n+   */\n+  template<\n+    typename _InputIterator\n+  >\n+  typename _Base::iterator\n+  insert(\n+    typename _Base::const_iterator __position,\n+    _InputIterator __first,\n+    _InputIterator __last)\n+  {\n+    if (size() + std::distance(__first, __last) > _UpperBound) {\n+      throw std::length_error(\"Exceeded upper bound\");\n+    }\n+    return _Base::insert(__position, __first, __last);\n+  }\n+\n+  using _Base::erase;\n+  using _Base::pop_back;\n+  using _Base::clear;\n+};\n+\n+/**\n+ *  @brief  Vector equality comparison.\n+ *  @param  __x  A %BoundedVector.\n+ *  @param  __y  A %BoundedVector of the same type as @a __x.\n+ *  @return  True if the size and elements of the vectors are equal.\n+ *\n+ *  This is an equivalence relation.  It is linear in the size of the\n+ *  vectors.  Vectors are considered equivalent if their sizes are equal,\n+ *  and if corresponding elements compare equal.\n+*/\n+template<typename _Tp, std::size_t _UpperBound, typename _Alloc>","path":"rosidl_generator_cpp/include/rosidl_generator_cpp/bounded_vector.hpp","position":621,"original_position":621,"commit_id":"1e4b0741cbd82da5e62b0822ab24f293ede12ba4","original_commit_id":"1e4b0741cbd82da5e62b0822ab24f293ede12ba4","user":{"login":"dirk-thomas","id":1335366,"avatar_url":"https://avatars.githubusercontent.com/u/1335366?v=3","gravatar_id":"","url":"https://api.github.com/users/dirk-thomas","html_url":"https://github.com/dirk-thomas","followers_url":"https://api.github.com/users/dirk-thomas/followers","following_url":"https://api.github.com/users/dirk-thomas/following{/other_user}","gists_url":"https://api.github.com/users/dirk-thomas/gists{/gist_id}","starred_url":"https://api.github.com/users/dirk-thomas/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dirk-thomas/subscriptions","organizations_url":"https://api.github.com/users/dirk-thomas/orgs","repos_url":"https://api.github.com/users/dirk-thomas/repos","events_url":"https://api.github.com/users/dirk-thomas/events{/privacy}","received_events_url":"https://api.github.com/users/dirk-thomas/received_events","type":"User","site_admin":false},"body":"Yes, different types can't be compared. I think that is sufficient for now.","created_at":"2016-06-23T23:00:15Z","updated_at":"2016-06-23T23:00:15Z","html_url":"https://github.com/ros2/rosidl/pull/158#discussion_r68330364","pull_request_url":"https://api.github.com/repos/ros2/rosidl/pulls/158","_links":{"self":{"href":"https://api.github.com/repos/ros2/rosidl/pulls/comments/68330364"},"html":{"href":"https://github.com/ros2/rosidl/pull/158#discussion_r68330364"},"pull_request":{"href":"https://api.github.com/repos/ros2/rosidl/pulls/158"}}},"pull_request":{"url":"https://api.github.com/repos/ros2/rosidl/pulls/158","id":74872553,"html_url":"https://github.com/ros2/rosidl/pull/158","diff_url":"https://github.com/ros2/rosidl/pull/158.diff","patch_url":"https://github.com/ros2/rosidl/pull/158.patch","issue_url":"https://api.github.com/repos/ros2/rosidl/issues/158","number":158,"state":"open","locked":false,"title":"add bounded_vector","user":{"login":"dirk-thomas","id":1335366,"avatar_url":"https://avatars.githubusercontent.com/u/1335366?v=3","gravatar_id":"","url":"https://api.github.com/users/dirk-thomas","html_url":"https://github.com/dirk-thomas","followers_url":"https://api.github.com/users/dirk-thomas/followers","following_url":"https://api.github.com/users/dirk-thomas/following{/other_user}","gists_url":"https://api.github.com/users/dirk-thomas/gists{/gist_id}","starred_url":"https://api.github.com/users/dirk-thomas/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dirk-thomas/subscriptions","organizations_url":"https://api.github.com/users/dirk-thomas/orgs","repos_url":"https://api.github.com/users/dirk-thomas/repos","events_url":"https://api.github.com/users/dirk-thomas/events{/privacy}","received_events_url":"https://api.github.com/users/dirk-thomas/received_events","type":"User","site_admin":false},"body":"The new custom container `BoundedVector` uses a template parameter to specify the upper bound because that enables to internally subclass `std::vector` (which safes us from writing a lot more code). If the upper bound would be passed to the constructor it would need to be stored in a member variable which would make the class not a POD anymore (when still subclassing) and that doesn't work with our type support code for introspection which relies on accessing the message fields using `offsetof`.\r\n\r\n* http://ci.ros2.org/job/ci_linux/1516/ (compared to master http://ci.ros2.org/job/ci_linux/1515/)\r\n* http://ci.ros2.org/job/ci_osx/1185/ (compared to master http://ci.ros2.org/job/ci_osx/1183/)\r\n* http://ci.ros2.org/job/ci_windows/1519/ (compared to master http://ci.ros2.org/job/ci_windows/1517/)","created_at":"2016-06-22T23:06:18Z","updated_at":"2016-06-23T23:00:15Z","closed_at":null,"merged_at":null,"merge_commit_sha":"3b9b5a91182db30351479eee3ea3dc1f81629527","assignee":{"login":"dirk-thomas","id":1335366,"avatar_url":"https://avatars.githubusercontent.com/u/1335366?v=3","gravatar_id":"","url":"https://api.github.com/users/dirk-thomas","html_url":"https://github.com/dirk-thomas","followers_url":"https://api.github.com/users/dirk-thomas/followers","following_url":"https://api.github.com/users/dirk-thomas/following{/other_user}","gists_url":"https://api.github.com/users/dirk-thomas/gists{/gist_id}","starred_url":"https://api.github.com/users/dirk-thomas/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dirk-thomas/subscriptions","organizations_url":"https://api.github.com/users/dirk-thomas/orgs","repos_url":"https://api.github.com/users/dirk-thomas/repos","events_url":"https://api.github.com/users/dirk-thomas/events{/privacy}","received_events_url":"https://api.github.com/users/dirk-thomas/received_events","type":"User","site_admin":false},"milestone":null,"commits_url":"https://api.github.com/repos/ros2/rosidl/pulls/158/commits","review_comments_url":"https://api.github.com/repos/ros2/rosidl/pulls/158/comments","review_comment_url":"https://api.github.com/repos/ros2/rosidl/pulls/comments{/number}","comments_url":"https://api.github.com/repos/ros2/rosidl/issues/158/comments","statuses_url":"https://api.github.com/repos/ros2/rosidl/statuses/1e4b0741cbd82da5e62b0822ab24f293ede12ba4","head":{"label":"ros2:bounded_vector","ref":"bounded_vector","sha":"1e4b0741cbd82da5e62b0822ab24f293ede12ba4","user":{"login":"ros2","id":3979232,"avatar_url":"https://avatars.githubusercontent.com/u/3979232?v=3","gravatar_id":"","url":"https://api.github.com/users/ros2","html_url":"https://github.com/ros2","followers_url":"https://api.github.com/users/ros2/followers","following_url":"https://api.github.com/users/ros2/following{/other_user}","gists_url":"https://api.github.com/users/ros2/gists{/gist_id}","starred_url":"https://api.github.com/users/ros2/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ros2/subscriptions","organizations_url":"https://api.github.com/users/ros2/orgs","repos_url":"https://api.github.com/users/ros2/repos","events_url":"https://api.github.com/users/ros2/events{/privacy}","received_events_url":"https://api.github.com/users/ros2/received_events","type":"Organization","site_admin":false},"repo":{"id":21748344,"name":"rosidl","full_name":"ros2/rosidl","owner":{"login":"ros2","id":3979232,"avatar_url":"https://avatars.githubusercontent.com/u/3979232?v=3","gravatar_id":"","url":"https://api.github.com/users/ros2","html_url":"https://github.com/ros2","followers_url":"https://api.github.com/users/ros2/followers","following_url":"https://api.github.com/users/ros2/following{/other_user}","gists_url":"https://api.github.com/users/ros2/gists{/gist_id}","starred_url":"https://api.github.com/users/ros2/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ros2/subscriptions","organizations_url":"https://api.github.com/users/ros2/orgs","repos_url":"https://api.github.com/users/ros2/repos","events_url":"https://api.github.com/users/ros2/events{/privacy}","received_events_url":"https://api.github.com/users/ros2/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/ros2/rosidl","description":"Packages which provide the ROS IDL (.msg) definition and code generation.","fork":false,"url":"https://api.github.com/repos/ros2/rosidl","forks_url":"https://api.github.com/repos/ros2/rosidl/forks","keys_url":"https://api.github.com/repos/ros2/rosidl/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ros2/rosidl/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ros2/rosidl/teams","hooks_url":"https://api.github.com/repos/ros2/rosidl/hooks","issue_events_url":"https://api.github.com/repos/ros2/rosidl/issues/events{/number}","events_url":"https://api.github.com/repos/ros2/rosidl/events","assignees_url":"https://api.github.com/repos/ros2/rosidl/assignees{/user}","branches_url":"https://api.github.com/repos/ros2/rosidl/branches{/branch}","tags_url":"https://api.github.com/repos/ros2/rosidl/tags","blobs_url":"https://api.github.com/repos/ros2/rosidl/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ros2/rosidl/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ros2/rosidl/git/refs{/sha}","trees_url":"https://api.github.com/repos/ros2/rosidl/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ros2/rosidl/statuses/{sha}","languages_url":"https://api.github.com/repos/ros2/rosidl/languages","stargazers_url":"https://api.github.com/repos/ros2/rosidl/stargazers","contributors_url":"https://api.github.com/repos/ros2/rosidl/contributors","subscribers_url":"https://api.github.com/repos/ros2/rosidl/subscribers","subscription_url":"https://api.github.com/repos/ros2/rosidl/subscription","commits_url":"https://api.github.com/repos/ros2/rosidl/commits{/sha}","git_commits_url":"https://api.github.com/repos/ros2/rosidl/git/commits{/sha}","comments_url":"https://api.github.com/repos/ros2/rosidl/comments{/number}","issue_comment_url":"https://api.github.com/repos/ros2/rosidl/issues/comments{/number}","contents_url":"https://api.github.com/repos/ros2/rosidl/contents/{+path}","compare_url":"https://api.github.com/repos/ros2/rosidl/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ros2/rosidl/merges","archive_url":"https://api.github.com/repos/ros2/rosidl/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ros2/rosidl/downloads","issues_url":"https://api.github.com/repos/ros2/rosidl/issues{/number}","pulls_url":"https://api.github.com/repos/ros2/rosidl/pulls{/number}","milestones_url":"https://api.github.com/repos/ros2/rosidl/milestones{/number}","notifications_url":"https://api.github.com/repos/ros2/rosidl/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ros2/rosidl/labels{/name}","releases_url":"https://api.github.com/repos/ros2/rosidl/releases{/id}","deployments_url":"https://api.github.com/repos/ros2/rosidl/deployments","created_at":"2014-07-11T19:19:18Z","updated_at":"2016-01-15T00:44:02Z","pushed_at":"2016-06-23T21:13:22Z","git_url":"git://github.com/ros2/rosidl.git","ssh_url":"git@github.com:ros2/rosidl.git","clone_url":"https://github.com/ros2/rosidl.git","svn_url":"https://github.com/ros2/rosidl","homepage":"","size":838,"stargazers_count":3,"watchers_count":3,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":9,"mirror_url":null,"open_issues_count":12,"forks":9,"open_issues":12,"watchers":3,"default_branch":"master"}},"base":{"label":"ros2:master","ref":"master","sha":"64e6a4462469382e292b482f2413668b874a5f2f","user":{"login":"ros2","id":3979232,"avatar_url":"https://avatars.githubusercontent.com/u/3979232?v=3","gravatar_id":"","url":"https://api.github.com/users/ros2","html_url":"https://github.com/ros2","followers_url":"https://api.github.com/users/ros2/followers","following_url":"https://api.github.com/users/ros2/following{/other_user}","gists_url":"https://api.github.com/users/ros2/gists{/gist_id}","starred_url":"https://api.github.com/users/ros2/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ros2/subscriptions","organizations_url":"https://api.github.com/users/ros2/orgs","repos_url":"https://api.github.com/users/ros2/repos","events_url":"https://api.github.com/users/ros2/events{/privacy}","received_events_url":"https://api.github.com/users/ros2/received_events","type":"Organization","site_admin":false},"repo":{"id":21748344,"name":"rosidl","full_name":"ros2/rosidl","owner":{"login":"ros2","id":3979232,"avatar_url":"https://avatars.githubusercontent.com/u/3979232?v=3","gravatar_id":"","url":"https://api.github.com/users/ros2","html_url":"https://github.com/ros2","followers_url":"https://api.github.com/users/ros2/followers","following_url":"https://api.github.com/users/ros2/following{/other_user}","gists_url":"https://api.github.com/users/ros2/gists{/gist_id}","starred_url":"https://api.github.com/users/ros2/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ros2/subscriptions","organizations_url":"https://api.github.com/users/ros2/orgs","repos_url":"https://api.github.com/users/ros2/repos","events_url":"https://api.github.com/users/ros2/events{/privacy}","received_events_url":"https://api.github.com/users/ros2/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/ros2/rosidl","description":"Packages which provide the ROS IDL (.msg) definition and code generation.","fork":false,"url":"https://api.github.com/repos/ros2/rosidl","forks_url":"https://api.github.com/repos/ros2/rosidl/forks","keys_url":"https://api.github.com/repos/ros2/rosidl/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ros2/rosidl/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ros2/rosidl/teams","hooks_url":"https://api.github.com/repos/ros2/rosidl/hooks","issue_events_url":"https://api.github.com/repos/ros2/rosidl/issues/events{/number}","events_url":"https://api.github.com/repos/ros2/rosidl/events","assignees_url":"https://api.github.com/repos/ros2/rosidl/assignees{/user}","branches_url":"https://api.github.com/repos/ros2/rosidl/branches{/branch}","tags_url":"https://api.github.com/repos/ros2/rosidl/tags","blobs_url":"https://api.github.com/repos/ros2/rosidl/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ros2/rosidl/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ros2/rosidl/git/refs{/sha}","trees_url":"https://api.github.com/repos/ros2/rosidl/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ros2/rosidl/statuses/{sha}","languages_url":"https://api.github.com/repos/ros2/rosidl/languages","stargazers_url":"https://api.github.com/repos/ros2/rosidl/stargazers","contributors_url":"https://api.github.com/repos/ros2/rosidl/contributors","subscribers_url":"https://api.github.com/repos/ros2/rosidl/subscribers","subscription_url":"https://api.github.com/repos/ros2/rosidl/subscription","commits_url":"https://api.github.com/repos/ros2/rosidl/commits{/sha}","git_commits_url":"https://api.github.com/repos/ros2/rosidl/git/commits{/sha}","comments_url":"https://api.github.com/repos/ros2/rosidl/comments{/number}","issue_comment_url":"https://api.github.com/repos/ros2/rosidl/issues/comments{/number}","contents_url":"https://api.github.com/repos/ros2/rosidl/contents/{+path}","compare_url":"https://api.github.com/repos/ros2/rosidl/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ros2/rosidl/merges","archive_url":"https://api.github.com/repos/ros2/rosidl/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ros2/rosidl/downloads","issues_url":"https://api.github.com/repos/ros2/rosidl/issues{/number}","pulls_url":"https://api.github.com/repos/ros2/rosidl/pulls{/number}","milestones_url":"https://api.github.com/repos/ros2/rosidl/milestones{/number}","notifications_url":"https://api.github.com/repos/ros2/rosidl/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ros2/rosidl/labels{/name}","releases_url":"https://api.github.com/repos/ros2/rosidl/releases{/id}","deployments_url":"https://api.github.com/repos/ros2/rosidl/deployments","created_at":"2014-07-11T19:19:18Z","updated_at":"2016-01-15T00:44:02Z","pushed_at":"2016-06-23T21:13:22Z","git_url":"git://github.com/ros2/rosidl.git","ssh_url":"git@github.com:ros2/rosidl.git","clone_url":"https://github.com/ros2/rosidl.git","svn_url":"https://github.com/ros2/rosidl","homepage":"","size":838,"stargazers_count":3,"watchers_count":3,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":9,"mirror_url":null,"open_issues_count":12,"forks":9,"open_issues":12,"watchers":3,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/ros2/rosidl/pulls/158"},"html":{"href":"https://github.com/ros2/rosidl/pull/158"},"issue":{"href":"https://api.github.com/repos/ros2/rosidl/issues/158"},"comments":{"href":"https://api.github.com/repos/ros2/rosidl/issues/158/comments"},"review_comments":{"href":"https://api.github.com/repos/ros2/rosidl/pulls/158/comments"},"review_comment":{"href":"https://api.github.com/repos/ros2/rosidl/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/ros2/rosidl/pulls/158/commits"},"statuses":{"href":"https://api.github.com/repos/ros2/rosidl/statuses/1e4b0741cbd82da5e62b0822ab24f293ede12ba4"}}}}
{"actor":{"display_login":"dirk-thomas"}}