浏览代码

[libcxx] [test] D26816: Fix non-Standard assumptions when testing sample().

sample() isn't specified with a reproducible algorithm, so expecting
exact output is non-Standard. Mark those tests with LIBCPP_ASSERT.

In test_small_population(), we're guaranteed to get all of the elements,
but not necessarily in their original order. When PopulationCategory is
forward, we're guaranteed stability (and can therefore test equal()).
Otherwise, we can only test is_permutation(). (As it happens, both libcxx
and MSVC's STL provide stability in this scenario for input-only iterators.)

git-svn-id: https://llvm.org/svn/llvm-project/libcxx/trunk@287383 91177308-0d34-0410-b5e6-96231b3b80d8
Stephan T. Lavavej 8 年之前
父节点
当前提交
0252201f9e
共有 1 个文件被更改,包括 14 次插入3 次删除
  1. 14 3
      test/std/algorithms/alg.modifying.operations/alg.random.sample/sample.pass.cpp

+ 14 - 3
test/std/algorithms/alg.modifying.operations/alg.random.sample/sample.pass.cpp

@@ -19,9 +19,11 @@
 
 
 #include <algorithm>
 #include <algorithm>
 #include <random>
 #include <random>
+#include <type_traits>
 #include <cassert>
 #include <cassert>
 
 
 #include "test_iterators.h"
 #include "test_iterators.h"
+#include "test_macros.h"
 
 
 struct ReservoirSampleExpectations {
 struct ReservoirSampleExpectations {
   enum { os = 4 };
   enum { os = 4 };
@@ -60,19 +62,23 @@ void test() {
   const unsigned os = Expectations::os;
   const unsigned os = Expectations::os;
   SampleItem oa[os];
   SampleItem oa[os];
   const int *oa1 = Expectations::oa1;
   const int *oa1 = Expectations::oa1;
+  ((void)oa1); // Prevent unused warning
   const int *oa2 = Expectations::oa2;
   const int *oa2 = Expectations::oa2;
+  ((void)oa2); // Prevent unused warning
   std::minstd_rand g;
   std::minstd_rand g;
   SampleIterator end;
   SampleIterator end;
   end = std::sample(PopulationIterator(ia),
   end = std::sample(PopulationIterator(ia),
                                   PopulationIterator(ia + is),
                                   PopulationIterator(ia + is),
                                   SampleIterator(oa), os, g);
                                   SampleIterator(oa), os, g);
   assert(end.base() - oa == std::min(os, is));
   assert(end.base() - oa == std::min(os, is));
-  assert(std::equal(oa, oa + os, oa1));
+  // sample() is deterministic but non-reproducible;
+  // its results can vary between implementations.
+  LIBCPP_ASSERT(std::equal(oa, oa + os, oa1));
   end = std::sample(PopulationIterator(ia),
   end = std::sample(PopulationIterator(ia),
                                   PopulationIterator(ia + is),
                                   PopulationIterator(ia + is),
                                   SampleIterator(oa), os, std::move(g));
                                   SampleIterator(oa), os, std::move(g));
   assert(end.base() - oa == std::min(os, is));
   assert(end.base() - oa == std::min(os, is));
-  assert(std::equal(oa, oa + os, oa2));
+  LIBCPP_ASSERT(std::equal(oa, oa + os, oa2));
 }
 }
 
 
 template <template<class...> class PopulationIteratorType, class PopulationItem,
 template <template<class...> class PopulationIteratorType, class PopulationItem,
@@ -122,7 +128,12 @@ void test_small_population() {
                                   PopulationIterator(ia + is),
                                   PopulationIterator(ia + is),
                                   SampleIterator(oa), os, g);
                                   SampleIterator(oa), os, g);
   assert(end.base() - oa == std::min(os, is));
   assert(end.base() - oa == std::min(os, is));
-  assert(std::equal(oa, end.base(), oa1));
+  typedef typename std::iterator_traits<PopulationIterator>::iterator_category PopulationCategory;
+  if (std::is_base_of<std::forward_iterator_tag, PopulationCategory>::value) {
+    assert(std::equal(oa, end.base(), oa1));
+  } else {
+    assert(std::is_permutation(oa, end.base(), oa1));
+  }
 }
 }
 
 
 int main() {
 int main() {