Bug fix for reversing OrderedGroups.

Reverse() method now handles the case where no groups exist.

Change-Id: Ia1ef08aa3cde01ceb71285b605a2e1f882c3b620
diff --git a/include/ceres/ordered_groups.h b/include/ceres/ordered_groups.h
index 74a3995..aa1bd3a 100644
--- a/include/ceres/ordered_groups.h
+++ b/include/ceres/ordered_groups.h
@@ -122,6 +122,10 @@
 
   // Reverse the order of the groups in place.
   void Reverse() {
+    if (NumGroups() == 0) {
+      return;
+    }
+
     typename std::map<int, std::set<T> >::reverse_iterator it =
         group_to_elements_.rbegin();
     std::map<int, std::set<T> > new_group_to_elements;
diff --git a/internal/ceres/ordered_groups_test.cc b/internal/ceres/ordered_groups_test.cc
index 5c2e3ec..4510686 100644
--- a/internal/ceres/ordered_groups_test.cc
+++ b/internal/ceres/ordered_groups_test.cc
@@ -159,6 +159,20 @@
   EXPECT_EQ(ordering.GroupId(x + 2), 2);
 }
 
+TEST(OrderedGroups, ReverseOrderingWithEmptyOrderedGroups) {
+  ParameterBlockOrdering ordering;
+  // This should be a no-op.
+  ordering.Reverse();
+
+  // Ensure the properties of an empty OrderedGroups still hold after Reverse().
+  EXPECT_EQ(ordering.NumGroups(), 0);
+  EXPECT_EQ(ordering.NumElements(), 0);
+  EXPECT_EQ(ordering.GroupSize(1), 0);
+  double x;
+  EXPECT_EQ(ordering.GroupId(&x), -1);
+  EXPECT_FALSE(ordering.Remove(&x));
+}
+
 TEST(OrderedGroups, BulkRemove) {
   ParameterBlockOrdering ordering;
   double x[3];