@@ -184,153 +184,6 @@ inline std::istream& operator>>(std::istream& in, uint8_t& value)
184184 return pcg_extras::operator >> <char >(in, value);
185185}
186186
187- /*
188- * The C++ SeedSeq concept (modelled by seed_seq) can fill an array of
189- * 32-bit integers with seed data, but sometimes we want to produce
190- * larger or smaller integers.
191- *
192- * The following code handles this annoyance.
193- *
194- * uneven_copy will copy an array of 32-bit ints to an array of larger or
195- * smaller ints (actually, the code is general it only needing forward
196- * iterators). The copy is identical to the one that would be performed if
197- * we just did memcpy on a standard little-endian machine, but works
198- * regardless of the endian of the machine (or the weirdness of the ints
199- * involved).
200- *
201- * generate_to initializes an array of integers using a SeedSeq
202- * object. It is given the size as a static constant at compile time and
203- * tries to avoid memory allocation. If we're filling in 32-bit constants
204- * we just do it directly. If we need a separate buffer and it's small,
205- * we allocate it on the stack. Otherwise, we fall back to heap allocation.
206- * Ugh.
207- *
208- * generate_one produces a single value of some integral type using a
209- * SeedSeq object.
210- */
211-
212- /* uneven_copy helper, case where destination ints are less than 32 bit. */
213-
214- template <class SrcIter , class DestIter >
215- SrcIter uneven_copy_impl (
216- SrcIter src_first, DestIter dest_first, DestIter dest_last,
217- std::true_type)
218- {
219- using src_t = typename std::iterator_traits<SrcIter>::value_type;
220- using dest_t = typename std::iterator_traits<DestIter>::value_type;
221-
222- constexpr bitcount_t SRC_SIZE = sizeof (src_t );
223- constexpr bitcount_t DEST_SIZE = sizeof (dest_t );
224- constexpr bitcount_t DEST_BITS = DEST_SIZE * 8 ;
225- constexpr bitcount_t SCALE = SRC_SIZE / DEST_SIZE;
226-
227- size_t count = 0 ;
228- src_t value = 0 ;
229-
230- while (dest_first != dest_last) {
231- if ((count++ % SCALE) == 0 )
232- value = *src_first++; // Get more bits
233- else
234- value >>= DEST_BITS; // Move down bits
235-
236- *dest_first++ = dest_t (value); // Truncates, ignores high bits.
237- }
238- return src_first;
239- }
240-
241- /* uneven_copy helper, case where destination ints are more than 32 bit. */
242-
243- template <class SrcIter , class DestIter >
244- SrcIter uneven_copy_impl (
245- SrcIter src_first, DestIter dest_first, DestIter dest_last,
246- std::false_type)
247- {
248- using src_t = typename std::iterator_traits<SrcIter>::value_type;
249- using dest_t = typename std::iterator_traits<DestIter>::value_type;
250-
251- constexpr auto SRC_SIZE = sizeof (src_t );
252- constexpr auto SRC_BITS = SRC_SIZE * 8 ;
253- constexpr auto DEST_SIZE = sizeof (dest_t );
254- constexpr auto SCALE = (DEST_SIZE+SRC_SIZE-1 ) / SRC_SIZE;
255-
256- while (dest_first != dest_last) {
257- dest_t value (0UL );
258- unsigned int shift = 0 ;
259-
260- for (size_t i = 0 ; i < SCALE; ++i) {
261- value |= dest_t (*src_first++) << shift;
262- shift += SRC_BITS;
263- }
264-
265- *dest_first++ = value;
266- }
267- return src_first;
268- }
269-
270- /* uneven_copy, call the right code for larger vs. smaller */
271-
272- template <class SrcIter , class DestIter >
273- inline SrcIter uneven_copy (SrcIter src_first,
274- DestIter dest_first, DestIter dest_last)
275- {
276- using src_t = typename std::iterator_traits<SrcIter>::value_type;
277- using dest_t = typename std::iterator_traits<DestIter>::value_type;
278-
279- constexpr bool DEST_IS_SMALLER = sizeof (dest_t ) < sizeof (src_t );
280-
281- return uneven_copy_impl (src_first, dest_first, dest_last,
282- std::integral_constant<bool , DEST_IS_SMALLER>{});
283- }
284-
285- /* generate_to, fill in a fixed-size array of integral type using a SeedSeq
286- * (actually works for any random-access iterator)
287- */
288-
289- template <size_t size, typename SeedSeq, typename DestIter>
290- inline void generate_to_impl (SeedSeq&& generator, DestIter dest,
291- std::true_type)
292- {
293- generator.generate (dest, dest+size);
294- }
295-
296- template <size_t size, typename SeedSeq, typename DestIter>
297- void generate_to_impl (SeedSeq&& generator, DestIter dest,
298- std::false_type)
299- {
300- using dest_t = typename std::iterator_traits<DestIter>::value_type;
301- constexpr auto DEST_SIZE = sizeof (dest_t );
302- constexpr auto GEN_SIZE = sizeof (uint32_t );
303-
304- constexpr bool GEN_IS_SMALLER = GEN_SIZE < DEST_SIZE;
305- constexpr size_t FROM_ELEMS =
306- GEN_IS_SMALLER
307- ? size * ((DEST_SIZE+GEN_SIZE-1 ) / GEN_SIZE)
308- : (size + (GEN_SIZE / DEST_SIZE) - 1 )
309- / ((GEN_SIZE / DEST_SIZE) + GEN_IS_SMALLER);
310- // this odd code ^^^^^^^^^^^^^^^^^ is work-around for
311- // a bug: http://llvm.org/bugs/show_bug.cgi?id=21287
312-
313- if constexpr (FROM_ELEMS <= 1024 ) {
314- uint32_t buffer[FROM_ELEMS];
315- generator.generate (buffer, buffer+FROM_ELEMS);
316- uneven_copy (buffer, dest, dest+size);
317- } else {
318- uint32_t * buffer = static_cast <uint32_t *>(malloc (GEN_SIZE * FROM_ELEMS));
319- generator.generate (buffer, buffer+FROM_ELEMS);
320- uneven_copy (buffer, dest, dest+size);
321- free (static_cast <void *>(buffer));
322- }
323- }
324-
325- template <size_t size, typename SeedSeq, typename DestIter>
326- inline void generate_to (SeedSeq&& generator, DestIter dest)
327- {
328- using dest_t = typename std::iterator_traits<DestIter>::value_type;
329- constexpr bool IS_32BIT = sizeof (dest_t ) == sizeof (uint32_t );
330-
331- generate_to_impl<size>(std::forward<SeedSeq>(generator), dest,
332- std::integral_constant<bool , IS_32BIT>{});
333- }
334187
335188/* generate_one, produce a value of integral type using a SeedSeq
336189 * (optionally, we can have it produce more than one and pick which one
0 commit comments