types/sized: update bits types to follow a more current style

This commit is contained in:
Danny Robson 2020-10-22 11:27:25 +10:00
parent 3fffacc19c
commit e22f4a9001
11 changed files with 120 additions and 123 deletions

View File

@ -553,7 +553,7 @@ list (
typeidx.cpp
typeidx.hpp
types.hpp
types/bits.hpp
types/sized.hpp
types/comparator.hpp
types/description.cpp
types/description.hpp

View File

@ -8,7 +8,6 @@
#pragma once
#include "types/bits.hpp"
#include "debug/assert.hpp"
#include <type_traits>

View File

@ -17,7 +17,6 @@
#include "../tuple/value.hpp"
#include "../debug/assert.hpp"
#include "../maths.hpp"
#include "../types/bits.hpp"
#include <cruft/util/preprocessor.hpp>

View File

@ -9,7 +9,7 @@
#pragma once
#include "std.hpp"
#include "types/bits.hpp"
#include "types/sized.hpp"
#include <compare>
#include <iosfwd>
@ -196,8 +196,8 @@ namespace cruft {
"endian conversion is only defined for integrals currently");
union {
typename sized_type<T>::sint sint;
typename sized_type<T>::uint uint;
typename types::sized::bytes<sizeof(T)>::sint sint;
typename types::sized::bytes<sizeof(T)>::uint uint;
};
if (std::is_signed<T>::value)

View File

@ -6,10 +6,9 @@
* Copyright 2011-2014 Danny Robson <danny@nerdcruft.net>
*/
#ifndef __UTIL_FIXED_HPP
#define __UTIL_FIXED_HPP
#pragma once
#include "types/bits.hpp"
#include "types/sized.hpp"
#include "maths.hpp"
#include <iosfwd>
@ -30,8 +29,8 @@ namespace cruft {
static_assert (E > 0);
static_assert ((I + E) % 8 == 0);
using sint_t = typename bits_type<I+E>::sint;
using uint_t = typename bits_type<I+E>::uint;
using sint_t = typename types::sized::bits<I+E>::sint;
using uint_t = typename types::sized::bits<I+E>::uint;
using native_type = typename std::conditional<
std::is_signed<T>::value,
@ -40,8 +39,8 @@ namespace cruft {
using integer_type = typename std::conditional<
std::is_signed<T>::value,
typename bits_type<divup (I, 8u) * 8u>::sint,
typename bits_type<divup (I, 8u) * 8u>::uint
typename types::sized::bits<divup (I, 8u) * 8u>::sint,
typename types::sized::bits<divup (I, 8u) * 8u>::uint
>::type;
explicit fixed (double);
@ -112,5 +111,3 @@ namespace cruft {
template <typename T, unsigned I, unsigned E>
std::ostream& operator<< (std::ostream&, fixed<T,I,E>);
}
#endif // __UTIL_FIXED_HPP

View File

@ -22,7 +22,7 @@ ieee_float<E, S>::ieee_float (void)
//-----------------------------------------------------------------------------
template <unsigned int E, unsigned int S>
ieee_float<E, S>::ieee_float (floating_t _floating):
ieee_float<E, S>::ieee_float (real_t _floating):
m_floating (_floating)
{ ; }
@ -72,16 +72,31 @@ ieee_float<E, S>::is_nan (void) const {
///////////////////////////////////////////////////////////////////////////////
namespace {
template <std::size_t BitsV, typename = void>
struct has_float : public std::false_type { };
template <std::size_t BitsV>
struct has_float<
BitsV,
std::void_t<
typename cruft::types::sized::bits<BitsV>::real
>
> : public std::true_type { };
}
//-----------------------------------------------------------------------------
template <unsigned int E, unsigned int S>
bool
ieee_float<E, S>::operator==(floating_t _floating) const {
ieee_float<E, S>::operator==(real_t _floating) const {
// TODO: This method really shouldn't be generated if there's no
// representative native floating point type. But I'm sick of
// C++'s template bullshit for tonight.
CHECK (bits_type<TOTAL_BITS>::has_floating);
CHECK (has_float<TOTAL_BITS>::value);
union {
floating_t _floating;
real_t _floating;
uint_t _uint;
} convertor;
@ -94,8 +109,8 @@ ieee_float<E, S>::operator==(floating_t _floating) const {
///////////////////////////////////////////////////////////////////////////////
template <unsigned int E, unsigned int S>
bool
ieee_float<E, S>::almost_equal (floating_t a,
floating_t b)
ieee_float<E, S>::almost_equal (real_t a,
real_t b)
{
return almost_equal (a, b, 128u);
}
@ -105,8 +120,8 @@ ieee_float<E, S>::almost_equal (floating_t a,
// Based on the Cygnus `AlmostEqual2sComplement` function
template <unsigned int E, unsigned int S>
bool
ieee_float<E, S>::almost_equal (floating_t _a,
floating_t _b,
ieee_float<E, S>::almost_equal (real_t _a,
real_t _b,
unsigned ulps)
{
// Ensure ULPs is small enough that the default NaNs won't compare as
@ -114,7 +129,7 @@ ieee_float<E, S>::almost_equal (floating_t _a,
CHECK_LE (ulps, 4 * 1024 * 1024u);
union {
floating_t f;
real_t f;
sint_t s;
uint_t u;
} a, b;
@ -132,9 +147,9 @@ ieee_float<E, S>::almost_equal (floating_t _a,
// Re-base negative floats to be continuous against +ve/-ve 0
static const union {
floating_t f;
real_t f;
sint_t s;
} NEG_ZERO { -floating_t {0} };
} NEG_ZERO { -real_t {0} };
if (a.s < 0)
a.s = NEG_ZERO.s - a.s;
@ -149,6 +164,6 @@ ieee_float<E, S>::almost_equal (floating_t _a,
///////////////////////////////////////////////////////////////////////////////
template class cruft::ieee_float< 5, 10>; // ieee_half
//template class cruft::ieee_float< 5, 10>; // ieee_half
template class cruft::ieee_float< 8, 23>; // ieee_single;
template class cruft::ieee_float<11, 52>; // ieee_double;

View File

@ -9,7 +9,7 @@
#ifndef __FLOAT_HPP
#define __FLOAT_HPP
#include "types/bits.hpp"
#include "types/sized.hpp"
///////////////////////////////////////////////////////////////////////////////
@ -24,14 +24,14 @@ namespace cruft {
static const unsigned int BIAS = (1 << (EXPONENT - 1)) - 1;
typedef typename bits_type<TOTAL_BITS>::sint sint_t;
typedef typename bits_type<TOTAL_BITS>::uint uint_t;
typedef typename bits_type<TOTAL_BITS>::floating floating_t;
using sint_t = typename types::sized::bits<TOTAL_BITS>::sint;
using uint_t = typename types::sized::bits<TOTAL_BITS>::uint;
using real_t = typename types::sized::bits<TOTAL_BITS>::real;
protected:
union {
uint_t m_bits;
floating_t m_floating;
uint_t m_bits;
real_t m_floating;
struct {
uint_t sign : 1;
@ -42,7 +42,7 @@ namespace cruft {
public:
ieee_float (void);
ieee_float (floating_t _floating);
ieee_float (real_t _floating);
ieee_float (const ieee_float &rhs);
static unsigned int bias (void)
@ -58,22 +58,22 @@ namespace cruft {
bool is_subnormal (void) const;
bool is_inifinity (void) const;
bool is_nan (void) const;
bool operator== (floating_t) const;
bool operator== (real_t) const;
static bool almost_equal (floating_t, floating_t);
static bool almost_equal (floating_t, floating_t, unsigned ulps);
static bool almost_equal (real_t, real_t);
static bool almost_equal (real_t, real_t, unsigned ulps);
};
typedef ieee_float< 5, 10> ieee_half;
//typedef ieee_float< 5, 10> ieee_half;
typedef ieee_float< 8, 23> ieee_single;
typedef ieee_float<11, 52> ieee_double;
extern template class ieee_float< 5,10>;
//extern template class ieee_float< 5,10>;
extern template class ieee_float< 8,23>;
extern template class ieee_float<11,52>;
static_assert (sizeof(ieee_half ) == 2, "ieee_half must be 2 bytes");
//static_assert (sizeof(ieee_half ) == 2, "ieee_half must be 2 bytes");
static_assert (sizeof(ieee_single ) == 4, "ieee_single must be 4 bytes");
static_assert (sizeof(ieee_double ) == 8, "ieee_double must be 8 bytes");
}

View File

@ -26,9 +26,14 @@ namespace cruft::geom::sample {
/// Approximate a poisson disc sampling through the "Mitchell's Best
/// Candidate" algorithm.
///
/// Try to keep adding a new point to a set. Each new point is the
/// best of a set of candidates. The 'best' is the point that is
/// furthest from all selected points.
/// We try to keep adding a new point to an output set.
/// * Generate `candidates_count` new points
/// * Remove any point that fails AcceptT
/// * Order the points by minimum distance to the output set
/// * Remove any point with a distance less than DistanceT
/// * Select the point with the highest distance
///
/// Keep iterating until no point is added to the output set.
///
/// \tparam SamplerT A surface sampler
/// \tparam DistanceT The type of point-to-point distances

View File

@ -6,10 +6,9 @@
* Copyright 2010-2016 Danny Robson <danny@nerdcruft.net>
*/
#ifndef __UTIL_HASH_FLETCHER_HPP
#define __UTIL_HASH_FLETCHER_HPP
#pragma once
#include "../types/bits.hpp"
#include "../types/sized.hpp"
#include "../view.hpp"
#include <cstdint>
@ -22,7 +21,7 @@ namespace cruft::hash {
class fletcher {
public:
using digest_t = DigestT;
using part_t = typename bytes_type<sizeof (digest_t) / 2>::uint;
using part_t = typename types::sized::bytes<sizeof (digest_t) / 2>::uint;
fletcher (part_t modulus, part_t a, part_t b);
@ -38,7 +37,3 @@ namespace cruft::hash {
const state_t m_initial;
};
}
#endif

View File

@ -1,72 +0,0 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright 2011 Danny Robson <danny@nerdcruft.net>
*/
#ifndef __UTIL_TYPES_BITS_HPP
#define __UTIL_TYPES_BITS_HPP
#include <cstdint>
#include <cstddef>
namespace cruft {
template <size_t BITS>
struct bits_type;
template <> struct bits_type< 8u> {
static const bool has_floating = false;
typedef uint8_t uint;
typedef int8_t sint;
typedef uint8_t floating;
};
template <> struct bits_type<16u> {
static const bool has_floating = false;
typedef uint16_t uint;
typedef int16_t sint;
typedef uint16_t floating;
};
template <> struct bits_type<32u> {
static const bool has_floating = true;
typedef uint32_t uint;
typedef int32_t sint;
typedef float floating;
};
template <> struct bits_type<64u> {
static const bool has_floating = true;
typedef uint64_t uint;
typedef int64_t sint;
typedef double floating;
};
template <size_t BYTES>
struct bytes_type : public bits_type<BYTES * 8u>
{ };
template <typename T>
struct sized_type : public bits_type<sizeof(T) * 8u>
{ };
template <std::size_t Size>
using bits_uint_t = typename bits_type<Size>::uint;
template <std::size_t Size>
using bytes_uint_t = typename bytes_type<Size>::uint;
}
#endif

59
types/sized.hpp Normal file
View File

@ -0,0 +1,59 @@
/*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright 2011-2020 Danny Robson <danny@nerdcruft.net>
*/
#pragma once
#include "../std.hpp"
#include <cstddef>
namespace cruft::types::sized {
template <size_t BITS>
struct bits;
template <>
struct bits< 8u> {
using uint = u08;
using sint = i08;
};
template <>
struct bits<16u> {
using uint = u16;
using sint = i16;
};
template <>
struct bits<32u> {
using uint = u32;
using sint = i32;
using real = f32;
};
template <>
struct bits<64u> {
using uint = u64;
using sint = i64;
using real = f64;
};
template <std::size_t BytesV>
struct bytes : public bits<BytesV * 8u>
{ };
template <typename BaseT>
struct sized_type : public bits<sizeof(BaseT) * 8u>
{ };
}