- /*
- * This helper returns the distance between two iterators if it is
- * possible to figure it out without messing up the range
- * (i.e. unless they are InputIterators). Otherwise this returns
- * -1.
- */
- template<class Iterator>
- int distance_if_multipass(Iterator first, Iterator last) {
- typedef typename std::iterator_traits<Iterator>::iterator_category categ;
- if (std::is_same<categ,std::input_iterator_tag>::value)
- return -1;
- return std::distance(first, last);
- }
-
- template<class OurContainer, class Vector, class GrowthPolicy>
- typename OurContainer::iterator
- insert_with_hint(OurContainer& sorted,
- Vector& cont,
- typename OurContainer::iterator hint,
- typename OurContainer::value_type&& value,
- GrowthPolicy& po)
- {
- const typename OurContainer::value_compare& cmp(sorted.value_comp());
- if (hint == cont.end() || cmp(value, *hint)) {
- if (hint == cont.begin()) {
- po.increase_capacity(cont, cont.begin());
- return cont.insert(cont.begin(), std::move(value));
- }
- if (cmp(*(hint - 1), value)) {
- hint = po.increase_capacity(cont, hint);
- return cont.insert(hint, std::move(value));
- }
+template <typename Compare, typename Key, typename T>
+struct sorted_vector_enable_if_is_transparent<
+ void_t<typename Compare::is_transparent>,
+ Compare,
+ Key,
+ T> {
+ using type = T;
+};
+
+// This wrapper goes around a GrowthPolicy and provides iterator
+// preservation semantics, but only if the growth policy is not the
+// default (i.e. nothing).
+template <class Policy>
+struct growth_policy_wrapper : private Policy {
+ template <class Container, class Iterator>
+ Iterator increase_capacity(Container& c, Iterator desired_insertion) {
+ typedef typename Container::difference_type diff_t;
+ diff_t d = desired_insertion - c.begin();
+ Policy::increase_capacity(c);
+ return c.begin() + d;
+ }
+};
+template <>
+struct growth_policy_wrapper<void> {
+ template <class Container, class Iterator>
+ Iterator increase_capacity(Container&, Iterator it) {
+ return it;
+ }
+};
+
+/*
+ * This helper returns the distance between two iterators if it is
+ * possible to figure it out without messing up the range
+ * (i.e. unless they are InputIterators). Otherwise this returns
+ * -1.
+ */
+template <class Iterator>
+int distance_if_multipass(Iterator first, Iterator last) {
+ typedef typename std::iterator_traits<Iterator>::iterator_category categ;
+ if (std::is_same<categ, std::input_iterator_tag>::value) {
+ return -1;
+ }
+ return std::distance(first, last);
+}
+
+template <class OurContainer, class Vector, class GrowthPolicy>
+typename OurContainer::iterator insert_with_hint(
+ OurContainer& sorted,
+ Vector& cont,
+ typename OurContainer::iterator hint,
+ typename OurContainer::value_type&& value,
+ GrowthPolicy& po) {
+ const typename OurContainer::value_compare& cmp(sorted.value_comp());
+ if (hint == cont.end() || cmp(value, *hint)) {
+ if (hint == cont.begin() || cmp(*(hint - 1), value)) {
+ hint = po.increase_capacity(cont, hint);
+ return cont.insert(hint, std::move(value));
+ } else {