text:
#pragma once

struct Memory;
struct State;

#include "Float.h"

namespace {

ALWAYS_INLINE static uint128_t __remill_read_memory_128(Memory *mem,
                                                        addr_t addr);

ALWAYS_INLINE static Memory *__remill_write_memory_128(Memory *mem, addr_t addr,
                                                       uint128_t val);

#define MAKE_UNDEF(n) \
  ALWAYS_INLINE static uint##n##_t Undefined(uint##n##_t) { \
    return __remill_undefined_##n(); \
  } \
  ALWAYS_INLINE static uint##n##_t Undefined(Rn<uint##n##_t>) { \
    return __remill_undefined_##n(); \
  } \
  ALWAYS_INLINE static uint##n##_t Undefined(RnW<uint##n##_t>) { \
    return __remill_undefined_##n(); \
  } \
  ALWAYS_INLINE static uint##n##_t Undefined(Mn<uint##n##_t>) { \
    return __remill_undefined_##n(); \
  } \
  ALWAYS_INLINE static uint##n##_t Undefined(MnW<uint##n##_t>) { \
    return __remill_undefined_##n(); \
  }

MAKE_UNDEF(8)
MAKE_UNDEF(16)
MAKE_UNDEF(32)
MAKE_UNDEF(64)

#undef MAKE_UNDEF

#define READBIT(A, B) ((A >> B) & 1)

#define MAKE_SIGNED_MEM_ACCESS(size) \
  ALWAYS_INLINE static int##size##_t __remill_read_memory_s##size( \
      Memory *mem, addr_t addr) { \
    return static_cast<int##size##_t>(__remill_read_memory_##size(mem, addr)); \
  } \
\
  ALWAYS_INLINE static Memory *__remill_write_memory_s##size( \
      Memory *mem, addr_t addr, int##size##_t val) { \
    return __remill_write_memory_##size(mem, addr, \
                                        static_cast<uint##size##_t>(val)); \
  }

MAKE_SIGNED_MEM_ACCESS(8)
MAKE_SIGNED_MEM_ACCESS(16)
MAKE_SIGNED_MEM_ACCESS(32)
MAKE_SIGNED_MEM_ACCESS(64)
MAKE_SIGNED_MEM_ACCESS(128)

// Read a value directly.
ALWAYS_INLINE static bool _Read(Memory *, bool val) {
  return val;
}

// Read a value directly.
ALWAYS_INLINE static uint8_t _Read(Memory *, uint8_t val) {
  return val;
}

// Read a value directly.
ALWAYS_INLINE static uint16_t _Read(Memory *, uint16_t val) {
  return val;
}

// Read a value directly.
ALWAYS_INLINE static uint32_t _Read(Memory *, uint32_t val) {
  return val;
}

// Read a value directly.
ALWAYS_INLINE static uint64_t _Read(Memory *, uint64_t val) {
  return val;
}

// Read a value directly.
ALWAYS_INLINE static float32_t _Read(Memory *, float32_t val) {
  return val;
}

// Read a value directly.
ALWAYS_INLINE static float64_t _Read(Memory *, float64_t val) {
  return val;
}

ALWAYS_INLINE static float80_t _Read(Memory *, float80_t val) {
  return val;
}

ALWAYS_INLINE static float32_t _Read(Memory *, In<float32_t> imm) {
  return reinterpret_cast<const float32_t &>(imm.val);
}

ALWAYS_INLINE static float64_t _Read(Memory *, In<float64_t> imm) {
  return reinterpret_cast<const float64_t &>(imm.val);
}

ALWAYS_INLINE static float80_t _Read(Memory *, In<float80_t> imm) {
  return reinterpret_cast<const float80_t &>(imm.val);
}

template <typename T>
ALWAYS_INLINE static T _Read(Memory *, In<T> imm) {
  return static_cast<T>(imm.val);
}

template <typename T>
ALWAYS_INLINE static T _Read(Memory *, Rn<T> reg) {
  return static_cast<T>(reg.val);
}

template <typename T>
ALWAYS_INLINE static T _Read(Memory *, RnW<T> reg) {
  return static_cast<T>(*(reg.val_ref));
}

// Make read operators for reading integral values from memory.
#define MAKE_MREAD(size, ret_size, type_prefix, access_suffix) \
  ALWAYS_INLINE static type_prefix##ret_size##_t _Read( \
      Memory *&memory, Mn<type_prefix##size##_t> op) { \
    return __remill_read_memory_##access_suffix(memory, op.addr); \
  } \
\
  ALWAYS_INLINE static type_prefix##ret_size##_t _Read( \
      Memory *&memory, MnW<type_prefix##size##_t> op) { \
    return __remill_read_memory_##access_suffix(memory, op.addr); \
  }

MAKE_MREAD(8, 8, uint, 8)
MAKE_MREAD(16, 16, uint, 16)
MAKE_MREAD(32, 32, uint, 32)
MAKE_MREAD(64, 64, uint, 64)
MAKE_MREAD(128, 128, uint, 128)

MAKE_MREAD(32, 32, float, f32)
MAKE_MREAD(64, 64, float, f64)

#undef MAKE_MREAD

ALWAYS_INLINE static float80_t _Read(Memory *&memory, Mn<float80_t> op) {
  native_float80_t val;
  memory = __remill_read_memory_f80(memory, op.addr, val);
  return val;
}

ALWAYS_INLINE static float80_t _Read(Memory *&memory, MnW<float80_t> op) {
  native_float80_t val;
  memory = __remill_read_memory_f80(memory, op.addr, val);
  return val;
}

// Basic write form for references.
template <typename T>
ALWAYS_INLINE static Memory *_Write(Memory *memory, T &dst, T src) {
  dst = src;
  return memory;
}

// Make write operators for writing values to registers.
#define MAKE_RWRITE(type) \
  ALWAYS_INLINE static Memory *_Write(Memory *memory, RnW<type> reg, \
                                      type val) { \
    *(reg.val_ref) = val; \
    return memory; \
  }

MAKE_RWRITE(uint8_t)
MAKE_RWRITE(uint16_t)
MAKE_RWRITE(uint32_t)
MAKE_RWRITE(uint64_t)
MAKE_RWRITE(float32_t)
MAKE_RWRITE(float64_t)
MAKE_RWRITE(float80_t)

#undef MAKE_RWRITE

// Make write operators for writing values to memory.
#define MAKE_MWRITE(size, write_size, mem_prefix, type_prefix, access_suffix) \
  ALWAYS_INLINE static Memory *_Write(Memory *memory, \
                                      MnW<mem_prefix##size##_t> op, \
                                      type_prefix##write_size##_t val) { \
    return __remill_write_memory_##access_suffix(memory, op.addr, val); \
  }

MAKE_MWRITE(8, 8, uint, uint, 8)
MAKE_MWRITE(16, 16, uint, uint, 16)
MAKE_MWRITE(32, 32, uint, uint, 32)
MAKE_MWRITE(64, 64, uint, uint, 64)
MAKE_MWRITE(128, 128, uint, uint, 128)

MAKE_MWRITE(32, 32, float, float, f32)
MAKE_MWRITE(64, 64, float, float, f64)
MAKE_MWRITE(80, 80, float, float, f80)

#undef MAKE_MWRITE

#define MAKE_READRV(prefix, size, accessor, base_type) \
  template <typename T> \
  ALWAYS_INLINE static auto _##prefix##ReadV##size(Memory *, RVnW<T> vec) \
      ->decltype(T().accessor) { \
    return reinterpret_cast<T *>(vec.val_ref)->accessor; \
  } \
\
  template <typename T> \
  ALWAYS_INLINE static auto _##prefix##ReadV##size(Memory *, RVn<T> vec) \
      ->decltype(T().accessor) { \
    return reinterpret_cast<const T *>(&vec.val)->accessor; \
  }

MAKE_READRV(U, 8, bytes, uint8_t)
MAKE_READRV(U, 16, words, uint16_t)
MAKE_READRV(U, 32, dwords, uint32_t)
MAKE_READRV(U, 64, qwords, uint64_t)

MAKE_READRV(S, 8, sbytes, int8_t)
MAKE_READRV(S, 16, swords, int16_t)
MAKE_READRV(S, 32, sdwords, int32_t)
MAKE_READRV(S, 64, sqwords, int64_t)

MAKE_READRV(F, 32, floats, float32_t)
MAKE_READRV(F, 64, doubles, float64_t)
MAKE_READRV(F, 80, tdoubles, float80_t)

#undef MAKE_READRV

#define MAKE_READV(prefix, size, accessor) \
  template <typename T> \
  ALWAYS_INLINE static auto _##prefix##ReadV##size(Memory *, VnW<T> vec) \
      ->decltype(T().accessor) { \
    return reinterpret_cast<T *>(vec.val_ref)->accessor; \
  } \
\
  template <typename T> \
  ALWAYS_INLINE static auto _##prefix##ReadV##size(Memory *, Vn<T> vec) \
      ->decltype(T().accessor) { \
    return reinterpret_cast<const T *>(vec.val)->accessor; \
  }

MAKE_READV(U, 8, bytes)
MAKE_READV(U, 16, words)
MAKE_READV(U, 32, dwords)
MAKE_READV(U, 64, qwords)
MAKE_READV(U, 128, dqwords)

MAKE_READV(S, 8, sbytes)
MAKE_READV(S, 16, swords)
MAKE_READV(S, 32, sdwords)
MAKE_READV(S, 64, sqwords)
MAKE_READV(S, 128, sdqwords)

MAKE_READV(F, 32, floats)
MAKE_READV(F, 64, doubles)
MAKE_READV(F, 80, tdouble)

#undef MAKE_READV

#define MAKE_MREADV(prefix, size, vec_accessor, mem_accessor) \
  template <typename T> \
  ALWAYS_INLINE static auto _##prefix##ReadV##size(Memory *memory, MVn<T> mem) \
      ->decltype(T().vec_accessor) { \
    decltype(T().vec_accessor) vec = {}; \
    const addr_t el_size = sizeof(vec.elems[0]); \
    _Pragma("unroll") for (addr_t i = 0; i < NumVectorElems(vec); ++i) { \
      vec.elems[i] = __remill_read_memory_##mem_accessor( \
          memory, mem.addr + (i * el_size)); \
    } \
    return vec; \
  } \
\
  template <typename T> \
  ALWAYS_INLINE static auto _##prefix##ReadV##size(Memory *memory, \
                                                   MVnW<T> mem) \
      ->decltype(T().vec_accessor) { \
    decltype(T().vec_accessor) vec = {}; \
    const addr_t el_size = sizeof(vec.elems[0]); \
    _Pragma("unroll") for (addr_t i = 0; i < NumVectorElems(vec); ++i) { \
      vec.elems[i] = __remill_read_memory_##mem_accessor( \
          memory, mem.addr + (i * el_size)); \
    } \
    return vec; \
  }

MAKE_MREADV(U, 8, bytes, 8)
MAKE_MREADV(U, 16, words, 16)
MAKE_MREADV(U, 32, dwords, 32)
MAKE_MREADV(U, 64, qwords, 64)
MAKE_MREADV(U, 128, dqwords, 128)

MAKE_MREADV(S, 8, sbytes, s8)
MAKE_MREADV(S, 16, swords, s16)
MAKE_MREADV(S, 32, sdwords, s32)
MAKE_MREADV(S, 64, sqwords, s64)
MAKE_MREADV(S, 128, sdqwords, s128)

MAKE_MREADV(F, 32, floats, f32)
MAKE_MREADV(F, 64, doubles, f64)
MAKE_MREADV(F, 80, tdoubles, f80)

#undef MAKE_MREADV

#define MAKE_WRITEV(prefix, size, accessor, kind, base_type) \
  template <typename T> \
  ALWAYS_INLINE static Memory *_##prefix##WriteV##size( \
      Memory *memory, kind<T> vec, base_type val) { \
    auto &sub_vec = reinterpret_cast<T *>(vec.val_ref)->accessor; \
    sub_vec.elems[0] = val; \
    _Pragma("unroll") for (addr_t i = 1; i < NumVectorElems(sub_vec); ++i) { \
      sub_vec.elems[i] = 0; \
    } \
    return memory; \
  } \
\
  template <typename T, typename V> \
  ALWAYS_INLINE static Memory *_##prefix##WriteV##size( \
      Memory *memory, kind<T> vec, const V &val) { \
    static_assert(sizeof(T) >= sizeof(V), "Object to WriteV is too big."); \
    typedef decltype(T().accessor.elems[0]) BT; \
    typedef decltype(V().elems[0]) VT; \
    static_assert(std::is_same<BT, VT>::value, \
                  "Incompatible types to a write to a vector register"); \
    auto &sub_vec = reinterpret_cast<T *>(vec.val_ref)->accessor; \
    _Pragma("unroll") for (addr_t i = 0; i < NumVectorElems(val); ++i) { \
      sub_vec.elems[i] = val.elems[i]; \
    } \
    _Pragma("unroll") for (addr_t i = NumVectorElems(val); \
                           i < NumVectorElems(sub_vec); ++i) { \
      sub_vec.elems[i] = 0; \
    } \
    return memory; \
  }

MAKE_WRITEV(U, 8, bytes, VnW, uint8_t)
MAKE_WRITEV(U, 16, words, VnW, uint16_t)
MAKE_WRITEV(U, 32, dwords, VnW, uint32_t)
MAKE_WRITEV(U, 64, qwords, VnW, uint64_t)
MAKE_WRITEV(U, 128, dqwords, VnW, uint128_t)

MAKE_WRITEV(S, 8, sbytes, VnW, int8_t)
MAKE_WRITEV(S, 16, swords, VnW, int16_t)
MAKE_WRITEV(S, 32, sdwords, VnW, int32_t)
MAKE_WRITEV(S, 64, sqwords, VnW, int64_t)
MAKE_WRITEV(S, 128, sdqwords, VnW, int128_t)

MAKE_WRITEV(F, 32, floats, VnW, float32_t)
MAKE_WRITEV(F, 64, doubles, VnW, float64_t)
MAKE_WRITEV(F, 80, tdoubles, VnW, float80_t)

MAKE_WRITEV(U, 8, bytes, RVnW, uint8_t)
MAKE_WRITEV(U, 16, words, RVnW, uint16_t)
MAKE_WRITEV(U, 32, dwords, RVnW, uint32_t)
MAKE_WRITEV(U, 64, qwords, RVnW, uint64_t)

MAKE_WRITEV(S, 8, sbytes, RVnW, int8_t)
MAKE_WRITEV(S, 16, swords, RVnW, int16_t)
MAKE_WRITEV(S, 32, sdwords, RVnW, int32_t)
MAKE_WRITEV(S, 64, sqwords, RVnW, int64_t)

MAKE_WRITEV(F, 32, floats, RVnW, float32_t)
MAKE_WRITEV(F, 64, doubles, RVnW, float64_t)
MAKE_WRITEV(F, 80, tdoubles, RVnW, float80_t)

#undef MAKE_WRITEV

#define MAKE_MWRITEV(prefix, size, vec_accessor, mem_accessor, base_type) \
  template <typename T> \
  ALWAYS_INLINE static Memory *_##prefix##WriteV##size( \
      Memory *memory, MVnW<T> mem, base_type val) { \
    T vec{}; \
    const addr_t el_size = sizeof(base_type); \
    vec.vec_accessor.elems[0] = val; \
    _Pragma("unroll") for (addr_t i = 0; i < NumVectorElems(vec.vec_accessor); \
                           ++i) { \
      memory = __remill_write_memory_##mem_accessor( \
          memory, mem.addr + (i * el_size), vec.vec_accessor.elems[i]); \
    } \
    return memory; \
  } \
\
  template <typename T, typename V> \
  ALWAYS_INLINE static Memory *_##prefix##WriteV##size( \
      Memory *memory, MVnW<T> mem, const V &val) { \
    static_assert(sizeof(T) == sizeof(V), "Invalid value size for MVnW."); \
    typedef decltype(T().vec_accessor) BT; \
    typedef decltype(V()) VT; \
    static_assert(std::is_same<BT, VT>::value, \
                  "Incompatible types to a write to a vector register"); \
    const addr_t el_size = sizeof(base_type); \
    _Pragma("unroll") for (addr_t i = 0; i < NumVectorElems(val); ++i) { \
      memory = __remill_write_memory_##mem_accessor( \
          memory, mem.addr + (i * el_size), val.elems[i]); \
    } \
    return memory; \
  }

MAKE_MWRITEV(U, 8, bytes, 8, uint8_t)
MAKE_MWRITEV(U, 16, words, 16, uint16_t)
MAKE_MWRITEV(U, 32, dwords, 32, uint32_t)
MAKE_MWRITEV(U, 64, qwords, 64, uint64_t)
MAKE_MWRITEV(U, 128, dqwords, 128, uint128_t)

MAKE_MWRITEV(S, 8, sbytes, s8, int8_t)
MAKE_MWRITEV(S, 16, swords, s16, int16_t)
MAKE_MWRITEV(S, 32, sdwords, s32, int32_t)
MAKE_MWRITEV(S, 64, sqwords, s64, int64_t)
MAKE_MWRITEV(S, 128, sdqwords, s128, int128_t)

MAKE_MWRITEV(F, 32, floats, f32, float32_t)
MAKE_MWRITEV(F, 64, doubles, f64, float64_t)
MAKE_MWRITEV(F, 80, tdoubles, f80, float80_t)

#undef MAKE_MWRITEV

#define MAKE_WRITE_REF(type) \
  ALWAYS_INLINE static Memory *_Write(Memory *memory, type &ref, type val) { \
    ref = val; \
    return memory; \
  }

MAKE_WRITE_REF(bool)
MAKE_WRITE_REF(uint8_t)
MAKE_WRITE_REF(uint16_t)
MAKE_WRITE_REF(uint32_t)
MAKE_WRITE_REF(uint64_t)
MAKE_WRITE_REF(uint128_t)
MAKE_WRITE_REF(float32_t)
MAKE_WRITE_REF(float64_t)
MAKE_WRITE_REF(float80_t)

#undef MAKE_WRITE_REF

#define MAKE_CMPXCHG(size, type_prefix, access_suffix) \
  template <typename T> \
  ALWAYS_INLINE static bool _CmpXchg(Memory *&memory, RnW<T> op, \
                                     type_prefix##size##_t &expected, \
                                     type_prefix##size##_t desired) { \
    if (decltype(expected)(*op.val_ref) == expected) { \
      *op.val_ref = desired; \
      return true; \
    } else { \
      expected = *reinterpret_cast<type_prefix##size##_t *>(op.val_ref); \
      return false; \
    } \
  } \
\
  template <typename T> \
  ALWAYS_INLINE static bool _CmpXchg(Memory *&memory, MnW<T> op, \
                                     type_prefix##size##_t &expected, \
                                     type_prefix##size##_t desired) { \
    auto prev_val = expected; \
    memory = __remill_compare_exchange_memory_##access_suffix( \
        memory, op.addr, expected, desired); \
    return prev_val == expected; \
  }

MAKE_CMPXCHG(8, uint, 8)
MAKE_CMPXCHG(16, uint, 16)
MAKE_CMPXCHG(32, uint, 32)
MAKE_CMPXCHG(64, uint, 64)
MAKE_CMPXCHG(128, uint, 128)

#undef MAKE_CMPXCHG
#define UCmpXchg(op, oldval, newval) _CmpXchg(memory, op, oldval, newval)

#define MAKE_ATOMIC_INTRINSIC(name, intrinsic_name, size, type_prefix, op) \
  template <typename T> \
  ALWAYS_INLINE type_prefix##size##_t _U##name(Memory *&memory, MnW<T> addr, \
                                               type_prefix##size##_t value) { \
    memory = __remill_##intrinsic_name##_##size(memory, addr.addr, value); \
    return value; \
  } \
\
  template <typename T> \
  ALWAYS_INLINE type_prefix##size##_t _U##name(Memory *&memory, RnW<T> addr, \
                                               type_prefix##size##_t value) { \
    auto prev_value = \
        *reinterpret_cast<type_prefix##size##_t *>(addr.val_ref); \
    *addr.val_ref = prev_value op value; \
    return prev_value; \
  }

#define MAKE_ATOMIC(name, intrinsic_name, op) \
  MAKE_ATOMIC_INTRINSIC(name, intrinsic_name, 8, uint, op) \
  MAKE_ATOMIC_INTRINSIC(name, intrinsic_name, 16, uint, op) \
  MAKE_ATOMIC_INTRINSIC(name, intrinsic_name, 32, uint, op) \
  MAKE_ATOMIC_INTRINSIC(name, intrinsic_name, 64, uint, op)

MAKE_ATOMIC(FetchAdd, fetch_and_add, +)
MAKE_ATOMIC(FetchSub, fetch_and_sub, -)
MAKE_ATOMIC(FetchOr, fetch_and_or, |)
MAKE_ATOMIC(FetchAnd, fetch_and_and, &)
MAKE_ATOMIC(FetchXor, fetch_and_xor, ^)

#undef MAKE_ATOMIC
#undef MAKE_ATOMIC_INTRINSIC

#define UFetchAdd(op1, op2) _UFetchAdd(memory, op1, op2)
#define UFetchSub(op1, op2) _UFetchSub(memory, op1, op2)
#define UFetchOr(op1, op2) _UFetchOr(memory, op1, op2)
#define UFetchAnd(op1, op2) _UFetchAnd(memory, op1, op2)
#define UFetchXor(op1, op2) _UFetchXor(memory, op1, op2)

#define MAKE_ATOMIC_INTRINSIC(name, intrinsic_name, size, type_prefix, op) \
  template <typename T> \
  ALWAYS_INLINE type_prefix##size##_t _U##name(Memory *&memory, MnW<T> addr, \
                                               type_prefix##size##_t value) { \
    memory = __remill_##intrinsic_name##_##size(memory, addr.addr, value); \
    return value; \
  } \
\
  template <typename T> \
  ALWAYS_INLINE type_prefix##size##_t _U##name(Memory *&memory, RnW<T> addr, \
                                               type_prefix##size##_t value) { \
    auto prev_value = \
        *reinterpret_cast<type_prefix##size##_t *>(addr.val_ref); \
    *addr.val_ref = value; \
    return prev_value op value; \
  }

#define MAKE_ATOMIC(name, intrinsic_name, op) \
  MAKE_ATOMIC_INTRINSIC(name, intrinsic_name, 8, uint, op) \
  MAKE_ATOMIC_INTRINSIC(name, intrinsic_name, 16, uint, op) \
  MAKE_ATOMIC_INTRINSIC(name, intrinsic_name, 32, uint, op) \
  MAKE_ATOMIC_INTRINSIC(name, intrinsic_name, 64, uint, op)

MAKE_ATOMIC(AddFetch, add_and_fetch, +)
MAKE_ATOMIC(SubFetch, sub_and_fetch, -)
MAKE_ATOMIC(OrFetch, or_and_fetch, |)
MAKE_ATOMIC(AndFetch, and_and_fetch, &)
MAKE_ATOMIC(XorFetch, xor_and_fetch, ^)

#undef MAKE_ATOMIC
#undef MAKE_ATOMIC_INTRINSIC

#define UAddFetch(op1, op2) _UAddFetch(memory, op1, op2)
#define USubFetch(op1, op2) _USubFetch(memory, op1, op2)
#define UOrFetch(op1, op2) _UOrFetch(memory, op1, op2)
#define UAndFetch(op1, op2) _UAndFetch(memory, op1, op2)
#define UXorFetch(op1, op2) _UXorFetch(memory, op1, op2)

// For the sake of esthetics and hiding the small-step semantics of memory
// operands, we use this macros to implicitly pass in the `memory` operand,
// which we know will be defined in semantics functions.
#define Read(op) _Read(memory, op)

// Write a source value to a destination operand, where the sizes of the
// values must match.
#define Write(op, val) \
  do { \
    static_assert(sizeof(typename BaseType<decltype(op)>::BT) == sizeof(val), \
                  "Bad write!"); \
    memory = _Write(memory, op, (val)); \
  } while (false)

#if !defined(issignaling)

ALWAYS_INLINE bool issignaling(float32_t x) {
  const nan32_t x_nan = {x};
  return x_nan.exponent == 0xFFU && !x_nan.is_quiet_nan && x_nan.payload;
}

ALWAYS_INLINE bool issignaling(float64_t x) {
  const nan64_t x_nan = {x};
  return x_nan.exponent == 0x7FFU && !x_nan.is_quiet_nan && x_nan.payload;
}

ALWAYS_INLINE bool issignaling(float80_t x) {
#if defined(__x86_64__) || defined(__i386__) || defined(_M_X86)
// On non-x86 architectures, native_float80_t is defined as a double,
// which is identical to the float64_t definition above
  const nan80_t x_nan = {x};
  return x_nan.exponent == 0x7FFFU && !x_nan.is_quiet_nan && x_nan.payload && x_nan.interger_bit;
#else
  return issignaling(static_cast<native_float80_t>(x));
#endif
}

#endif  // !defined(issignaling)

template <typename T, typename R = typename IntegerType<T>::UT>
ALWAYS_INLINE static constexpr R ByteSizeOf(T) {
  return static_cast<R>(sizeof(typename BaseType<T>::BT));
}

template <typename T, typename R = typename IntegerType<T>::UT>
ALWAYS_INLINE static constexpr R BitSizeOf(T) {
  return static_cast<R>(sizeof(typename BaseType<T>::BT) * 8);
}

// Convert the input value into an unsigned integer.
template <typename T>
ALWAYS_INLINE static auto Unsigned(T val) -> typename IntegerType<T>::UT {
  return static_cast<typename IntegerType<T>::UT>(val);
}

// Convert the input value into a signed integer.
template <typename T>
ALWAYS_INLINE static auto Signed(T val) -> typename IntegerType<T>::ST {
  return static_cast<typename IntegerType<T>::ST>(val);
}

template <typename T>
ALWAYS_INLINE static uint8_t IsNegative(T x) {
  return static_cast<uint8_t>(std::signbit(x));
}

ALWAYS_INLINE static uint8_t IsNegative(float80_t x) {
  return static_cast<uint8_t>(std::signbit(static_cast<native_float80_t>(x)));
}

ALWAYS_INLINE static uint8_t IsZero(float32_t x) {
  return static_cast<uint8_t>(FP_ZERO == std::fpclassify(x));
}

ALWAYS_INLINE static uint8_t IsZero(float64_t x) {
  return static_cast<uint8_t>(FP_ZERO == std::fpclassify(x));
}

ALWAYS_INLINE static uint8_t IsZero(float80_t x) {
  return static_cast<uint8_t>(FP_ZERO == std::fpclassify(static_cast<native_float80_t>(x)));
}

ALWAYS_INLINE static uint8_t IsInfinite(float32_t x) {
  return static_cast<uint8_t>(FP_INFINITE == std::fpclassify(x));
}

ALWAYS_INLINE static uint8_t IsInfinite(float64_t x) {
  return static_cast<uint8_t>(FP_INFINITE == std::fpclassify(x));
}

ALWAYS_INLINE static uint8_t IsInfinite(float80_t x) {
  return static_cast<uint8_t>(FP_INFINITE == std::fpclassify(static_cast<native_float80_t>(x)));
}

ALWAYS_INLINE static uint8_t IsNaN(float32_t x) {
  return static_cast<uint8_t>(FP_NAN == std::fpclassify(x));
}

ALWAYS_INLINE static uint8_t IsNaN(float64_t x) {
  return static_cast<uint8_t>(FP_NAN == std::fpclassify(x));
}

ALWAYS_INLINE static uint8_t IsNaN(float80_t x) {
  return static_cast<uint8_t>(FP_NAN == std::fpclassify(static_cast<native_float80_t>(x)));
}

ALWAYS_INLINE static bool IsSignalingNaN(float32_t x) {
  const nan32_t x_nan = {x};
  return x_nan.exponent == 0xFFU && !x_nan.is_quiet_nan && x_nan.payload;
}

ALWAYS_INLINE static bool IsSignalingNaN(float64_t x) {
  const nan64_t x_nan = {x};
  return x_nan.exponent == 0x7FFU && !x_nan.is_quiet_nan && x_nan.payload;
}

ALWAYS_INLINE static bool IsSignalingNaN(float80_t x) {
#if defined(__x86_64__) || defined(__i386__) || defined(_M_X86)
// On non-x86 architectures, native_float80_t is defined as a double,
// which is identical to the float64_t definition above
  const nan80_t x_nan = {x};
  return x_nan.exponent == 0x7FFFU && !x_nan.is_quiet_nan && x_nan.payload && x_nan.interger_bit;
#else
  return IsSignalingNaN(static_cast<native_float80_t>(x));
#endif
}

template <typename T>
ALWAYS_INLINE static uint8_t IsSignalingNaN(T) {
  return 0;
}

template <typename T>
ALWAYS_INLINE static uint8_t IsDenormal(T x) {
  return static_cast<uint8_t>(FP_SUBNORMAL == std::fpclassify(x));
}

ALWAYS_INLINE static uint8_t IsDenormal(float32_t x) {
  return static_cast<uint8_t>(FP_SUBNORMAL == std::fpclassify(x));
}

ALWAYS_INLINE static uint8_t IsDenormal(float64_t x) {
  return static_cast<uint8_t>(FP_SUBNORMAL == std::fpclassify(x));
}

ALWAYS_INLINE static uint8_t IsDenormal(float80_t x) {
  return static_cast<uint8_t>(FP_SUBNORMAL == std::fpclassify(static_cast<native_float80_t>(x)));
}

#if defined(__x86_64__) || defined(__i386__) || defined(_M_X86)
// On non-x86 architectures, native_float80_t is defined as a double,
// which is identical to the float64_t definition above
ALWAYS_INLINE static uint8_t IsDenormal(native_float80_t x) {
  return static_cast<uint8_t>(FP_SUBNORMAL == std::fpclassify(static_cast<native_float80_t>(x)));
}
#endif

template <typename T>
ALWAYS_INLINE static uint8_t IsZero(T val) {
  return static_cast<uint8_t>(!val);
}

template <typename T>
ALWAYS_INLINE static uint8_t IsInfinite(T) {
  return 0;
}

template <typename T>
ALWAYS_INLINE static uint8_t IsNaN(T) {
  return 0;
}

// Return the largest possible value assignable to `val`.
template <typename T>
ALWAYS_INLINE static T Maximize(T) {
  return std::numeric_limits<T>::max();
}

// Return the smallest possible value assignable to `val`.
template <typename T>
ALWAYS_INLINE static T Minimize(T) {
  return std::numeric_limits<T>::min();
}

#define MAKE_CONVERT(dest_type, name) \
  template <typename T> \
  ALWAYS_INLINE static dest_type name(T val) { \
    return static_cast<dest_type>(val); \
  }

MAKE_CONVERT(int8_t, Int8)
MAKE_CONVERT(int16_t, Int16)
MAKE_CONVERT(int32_t, Int32)
MAKE_CONVERT(int64_t, Int64)
MAKE_CONVERT(int128_t, Int128)
MAKE_CONVERT(uint8_t, UInt8)
MAKE_CONVERT(uint16_t, UInt16)
MAKE_CONVERT(uint32_t, UInt32)
MAKE_CONVERT(uint64_t, UInt64)
MAKE_CONVERT(uint128_t, UInt128)
MAKE_CONVERT(float32_t, Float32)
MAKE_CONVERT(float64_t, Float64)
MAKE_CONVERT(float80_t, Float80)

#undef MAKE_CONVERT

// Return the value as-is. This is useful when making many accessors using
// macros, because it lets us decide to pull out values as-is, as unsigned
// integers, or as signed integers.
#define Identity(...) __VA_ARGS__

// Convert an integer to some other type. This is important for
// integer literals, whose type are `int`.
template <typename T, typename U>
ALWAYS_INLINE static auto Literal(U val) -> typename IntegerType<T>::BT {
  return static_cast<typename IntegerType<T>::BT>(val);
}

template <typename T, typename U>
ALWAYS_INLINE static auto ULiteral(U val) -> typename IntegerType<T>::UT {
  return static_cast<typename IntegerType<T>::UT>(val);
}

template <typename T, typename U>
ALWAYS_INLINE static auto SLiteral(U val) -> typename IntegerType<T>::ST {
  return static_cast<typename IntegerType<T>::ST>(val);
}

// Zero-extend an integer to twice its current width.
template <typename T>
ALWAYS_INLINE static auto ZExt(T val) -> typename IntegerType<T>::WUT {
  return static_cast<typename IntegerType<T>::WUT>(Unsigned(val));
}

// Zero-extend an integer type explicitly specified by `DT`. This is useful
// for things like writing to a possibly wider version of a register, but
// not knowing exactly how wide the wider version is.
template <typename DT, typename T>
ALWAYS_INLINE static auto ZExtTo(T val) -> typename IntegerType<DT>::UT {
  typedef typename IntegerType<DT>::UT UT;
  static_assert(sizeof(T) <= sizeof(typename IntegerType<DT>::BT),
                "Bad extension.");
  return static_cast<UT>(Unsigned(val));
}

// Sign-extend an integer to twice its current width.
template <typename T>
ALWAYS_INLINE static auto SExt(T val) -> typename IntegerType<T>::WST {
  return static_cast<typename IntegerType<T>::WST>(Signed(val));
}

// Zero-extend an integer type explicitly specified by `DT`.
template <typename DT, typename T>
ALWAYS_INLINE static auto SExtTo(T val) -> typename IntegerType<DT>::ST {
  static_assert(sizeof(T) <= sizeof(typename IntegerType<DT>::BT),
                "Bad extension.");
  return static_cast<typename IntegerType<DT>::ST>(Signed(val));
}

// Truncate an integer to half of its current width.
template <typename T>
ALWAYS_INLINE static auto Trunc(T val) ->
    typename NextSmallerIntegerType<T>::BT {
  return static_cast<typename NextSmallerIntegerType<T>::BT>(val);
}

// Truncate an integer to have the same width/sign as the type specified
// by `DT`.
template <typename DT, typename T>
ALWAYS_INLINE static auto TruncTo(T val) -> typename IntegerType<DT>::BT {
  static_assert(sizeof(T) >= sizeof(typename IntegerType<DT>::BT),
                "Bad truncation.");
  return static_cast<typename IntegerType<DT>::BT>(val);
}

#define WriteTrunc(op, val) \
  do { \
    Write(op, TruncTo<decltype(op)>(val)); \
  } while (false)

// Handle writes of N-bit values to M-bit values with N <= M. If N < M then the
// source value will be zero-extended to the dest value type. This is useful
// on x86-64 where writes to 32-bit registers zero-extend to 64-bits. In a
// 64-bit build of Remill, the `R32W` type used in the X86 architecture
// runtime actually aliases `R64W`.
#define WriteZExt(op, val) \
  do { \
    Write(op, ZExtTo<decltype(op)>(val)); \
  } while (false)

#define WriteSExt(op, val) \
  do { \
    Write(op, Unsigned(SExtTo<decltype(op)>(val))); \
  } while (false)

#define SWriteV8(op, val) \
  do { \
    memory = _SWriteV8(memory, op, (val)); \
  } while (false)

#define UWriteV8(op, val) \
  do { \
    memory = _UWriteV8(memory, op, (val)); \
  } while (false)

#define SWriteV16(op, val) \
  do { \
    memory = _SWriteV16(memory, op, (val)); \
  } while (false)

#define UWriteV16(op, val) \
  do { \
    memory = _UWriteV16(memory, op, (val)); \
  } while (false)

#define SWriteV32(op, val) \
  do { \
    memory = _SWriteV32(memory, op, (val)); \
  } while (false)

#define UWriteV32(op, val) \
  do { \
    memory = _UWriteV32(memory, op, (val)); \
  } while (false)

#define SWriteV64(op, val) \
  do { \
    memory = _SWriteV64(memory, op, (val)); \
  } while (false)

#define UWriteV64(op, val) \
  do { \
    memory = _UWriteV64(memory, op, (val)); \
  } while (false)

#define SWriteV128(op, val) \
  do { \
    memory = _SWriteV128(memory, op, (val)); \
  } while (false)

#define UWriteV128(op, val) \
  do { \
    memory = _UWriteV128(memory, op, (val)); \
  } while (false)

#define FWriteV32(op, val) \
  do { \
    memory = _FWriteV32(memory, op, (val)); \
  } while (false)

#define FWriteV64(op, val) \
  do { \
    memory = _FWriteV64(memory, op, (val)); \
  } while (false)

#define SReadV8(op) _SReadV8(memory, op)
#define UReadV8(op) _UReadV8(memory, op)

#define SReadV16(op) _SReadV16(memory, op)
#define UReadV16(op) _UReadV16(memory, op)

#define SReadV32(op) _SReadV32(memory, op)
#define UReadV32(op) _UReadV32(memory, op)

#define SReadV64(op) _SReadV64(memory, op)
#define UReadV64(op) _UReadV64(memory, op)

#define SReadV128(op) _SReadV128(memory, op)
#define UReadV128(op) _UReadV128(memory, op)

#define FReadV32(op) _FReadV32(memory, op)
#define FReadV64(op) _FReadV64(memory, op)

// Useful for stubbing out an operator.
#define MAKE_NOP(...)

// Unary operator.
#define MAKE_UOP(name, type, widen_type, op) \
  ALWAYS_INLINE static type name(type R) { \
    return static_cast<type>(op static_cast<widen_type>(R)); \
  }

// Binary operator.
#define MAKE_BINOP(name, type, widen_type, op) \
  ALWAYS_INLINE static type name(type L, type R) { \
    return static_cast<type>(static_cast<widen_type>(L) \
                                 op static_cast<widen_type>(R)); \
  }

#define MAKE_BOOLBINOP(name, type, widen_type, op) \
  ALWAYS_INLINE static bool name(type L, type R) { \
    return L op R; \
  }

// The purpose of the widening type is that Clang/LLVM will already extend
// the types of the inputs to their "natural" machine size, so we'll just
// make that explicit, where `addr_t` encodes the natural machine word.
#define MAKE_OPS(name, op, make_int_op, make_float_op) \
  make_int_op(U##name, uint8_t, addr_t, op) \
  make_int_op(U##name##8, uint8_t, addr_t,op) \
  make_int_op(U##name, uint16_t, addr_t, op) \
  make_int_op(U##name##16, uint16_t, addr_t, op) \
  make_int_op(U##name, uint32_t, addr_t, op) \
  make_int_op(U##name##32, uint32_t, addr_t, op) \
  make_int_op(U##name, uint64_t, uint64_t, op) \
  make_int_op(U##name##64, uint64_t, uint64_t, op) \
  make_int_op(U##name, uint128_t, uint128_t, op) \
  make_int_op(U##name##128, uint128_t, uint128_t, op) \
  make_int_op(S##name, int8_t, addr_diff_t, op) \
  make_int_op(S##name##8, int8_t, addr_diff_t, op) \
  make_int_op(S##name, int16_t, addr_diff_t, op) \
  make_int_op(S##name##16, int16_t, addr_diff_t, op) \
  make_int_op(S##name, int32_t, addr_diff_t, op) \
  make_int_op(S##name##32, int32_t, addr_diff_t, op) \
  make_int_op(S##name, int64_t, int64_t, op) \
  make_int_op(S##name##64, int64_t, int64_t, op) \
  make_int_op(S##name, int128_t, int128_t, op) \
  make_int_op(S##name##128, int128_t, int128_t, op) \
  make_float_op(F##name, float32_t, float32_t, op) \
  make_float_op(F##name##32, float32_t, float32_t, op) \
  make_float_op(F##name, float64_t, float64_t, op) \
  make_float_op(F##name##64, float64_t, float64_t, op) \
  make_float_op(F##name, float80_t, float80_t, op) \
  make_float_op(F##name##80, float80_t, float80_t, op)

MAKE_OPS(Add, +, MAKE_BINOP, MAKE_BINOP)
MAKE_OPS(Sub, -, MAKE_BINOP, MAKE_BINOP)
MAKE_OPS(Mul, *, MAKE_BINOP, MAKE_BINOP)
MAKE_OPS(Div, /, MAKE_BINOP, MAKE_BINOP)
MAKE_OPS(Rem, %, MAKE_BINOP, MAKE_NOP)
MAKE_OPS(And, &, MAKE_BINOP, MAKE_NOP)
MAKE_OPS(AndN, &~, MAKE_BINOP, MAKE_NOP)
MAKE_OPS(Or, |, MAKE_BINOP, MAKE_NOP)
MAKE_OPS(Xor, ^, MAKE_BINOP, MAKE_NOP)
MAKE_OPS(Shr, >>, MAKE_BINOP, MAKE_NOP)
MAKE_OPS(Shl, <<, MAKE_BINOP, MAKE_NOP)
MAKE_OPS(Neg, -, MAKE_UOP, MAKE_UOP)
MAKE_OPS(Not, ~, MAKE_UOP, MAKE_NOP)

template <typename T>
ALWAYS_INLINE static T Ror(T val_, T amount_) {
  using UT = typename IntegerType<T>::UT;
  constexpr UT width = static_cast<UT>(sizeof(UT) * 8);
  const UT val = static_cast<UT>(val_);
  const UT amount = static_cast<UT>(amount_) % width;
  if (!amount) {
    return val_;
  }
  const UT shifted_bits = val >> amount;
  const UT rotated_bits = val << (width - amount);
  return static_cast<T>(shifted_bits | rotated_bits);
}

template <typename T>
ALWAYS_INLINE static T Rol(T val_, T amount_) {
  using UT = typename IntegerType<T>::UT;
  constexpr UT width = static_cast<UT>(sizeof(val_) * 8);
  const UT val = static_cast<UT>(val_);
  const UT amount = static_cast<UT>(amount_) % width;
  if (!amount) {
    return val_;
  }
  UT low_bits = val >> (width - amount);
  UT high_bits = val << width;
  return static_cast<T>(low_bits | high_bits);
}

// TODO(pag): Handle unordered and ordered floating point comparisons.
MAKE_OPS(CmpEq, ==, MAKE_BOOLBINOP, MAKE_BOOLBINOP)
MAKE_OPS(CmpNeq, !=, MAKE_BOOLBINOP, MAKE_BOOLBINOP)
MAKE_OPS(CmpLt, <, MAKE_BOOLBINOP, MAKE_BOOLBINOP)
MAKE_OPS(CmpLte, <=, MAKE_BOOLBINOP, MAKE_BOOLBINOP)
MAKE_OPS(CmpGt, >, MAKE_BOOLBINOP, MAKE_BOOLBINOP)
MAKE_OPS(CmpGte, >=, MAKE_BOOLBINOP, MAKE_BOOLBINOP)

#undef MAKE_UNOP
#undef MAKE_BINOP
#undef MAKE_OPS

ALWAYS_INLINE static bool BAnd(bool a, bool b) {
  return a && b;
}

ALWAYS_INLINE static bool BOr(bool a, bool b) {
  return a || b;
}

ALWAYS_INLINE static bool BXor(bool a, bool b) {
  return a != b;
}

ALWAYS_INLINE static bool BXnor(bool a, bool b) {
  return a == b;
}

ALWAYS_INLINE static bool BNot(bool a) {
  return !a;
}

// Binary broadcast operator.
#define MAKE_BIN_BROADCAST(op, size, accessor) \
  template <typename T> \
  ALWAYS_INLINE static T op##V##size(const T &L, const T &R) { \
    T ret{}; \
    _Pragma("unroll") for (auto i = 0UL; i < NumVectorElems(L); ++i) { \
      ret.elems[i] = op(L.elems[i], R.elems[i]); \
    } \
    return ret; \
  }

// Unary broadcast operator.
#define MAKE_UN_BROADCAST(op, size, accessor) \
  template <typename T> \
  ALWAYS_INLINE static T op##V##size(const T &R) { \
    T ret{}; \
    _Pragma("unroll") for (auto i = 0UL; i < NumVectorElems(R); ++i) { \
      ret.elems[i] = op(R.elems[i]); \
    } \
    return ret; \
  }

#define MAKE_BROADCASTS(op, make_int_broadcast, make_float_broadcast) \
  make_int_broadcast(U##op, 8, bytes) make_int_broadcast(U##op, 16, words) \
      make_int_broadcast(U##op, 32, dwords) \
          make_int_broadcast(U##op, 64, qwords) \
              make_int_broadcast(S##op, 8, sbytes) \
                  make_int_broadcast(S##op, 16, swords) \
                      make_int_broadcast(S##op, 32, sdwords) \
                          make_int_broadcast(S##op, 64, sqwords) \
                              make_float_broadcast(F##op, 32, floats) \
                                  make_float_broadcast(F##op, 64, doubles)

MAKE_BROADCASTS(Add, MAKE_BIN_BROADCAST, MAKE_BIN_BROADCAST)
MAKE_BROADCASTS(Sub, MAKE_BIN_BROADCAST, MAKE_BIN_BROADCAST)
MAKE_BROADCASTS(Mul, MAKE_BIN_BROADCAST, MAKE_BIN_BROADCAST)
MAKE_BROADCASTS(Div, MAKE_BIN_BROADCAST, MAKE_BIN_BROADCAST)
MAKE_BROADCASTS(Rem, MAKE_BIN_BROADCAST, MAKE_NOP)
MAKE_BROADCASTS(And, MAKE_BIN_BROADCAST, MAKE_NOP)
MAKE_BROADCASTS(AndN, MAKE_BIN_BROADCAST, MAKE_NOP)
MAKE_BROADCASTS(Or, MAKE_BIN_BROADCAST, MAKE_NOP)
MAKE_BROADCASTS(Xor, MAKE_BIN_BROADCAST, MAKE_NOP)
MAKE_BROADCASTS(Shl, MAKE_BIN_BROADCAST, MAKE_NOP)
MAKE_BROADCASTS(Shr, MAKE_BIN_BROADCAST, MAKE_NOP)
MAKE_BROADCASTS(Neg, MAKE_UN_BROADCAST, MAKE_NOP)
MAKE_BROADCASTS(Not, MAKE_UN_BROADCAST, MAKE_NOP)

#undef MAKE_BIN_BROADCAST
#undef MAKE_UN_BROADCAST

// Binary broadcast operator.
#define MAKE_ACCUMULATE(op, size, accessor) \
  template <typename T> \
  ALWAYS_INLINE static auto Accumulate##op##V##size(T R)->decltype( \
      R.elems[0] | R.elems[1]) { \
    auto L = R.elems[0]; \
    _Pragma("unroll") for (auto i = 1UL; i < NumVectorElems(R); ++i) { \
      L = op(L, R.elems[i]); \
    } \
    return L; \
  }

MAKE_BROADCASTS(Add, MAKE_ACCUMULATE, MAKE_ACCUMULATE)
MAKE_BROADCASTS(And, MAKE_ACCUMULATE, MAKE_NOP)
MAKE_BROADCASTS(AndN, MAKE_ACCUMULATE, MAKE_NOP)
MAKE_BROADCASTS(Or, MAKE_ACCUMULATE, MAKE_NOP)
MAKE_BROADCASTS(Xor, MAKE_ACCUMULATE, MAKE_NOP)

#undef MAKE_ACCUMULATE
#undef MAKE_UN_BROADCAST
#undef MAKE_BROADCASTS
#undef MAKE_NOP

template <typename T>
ALWAYS_INLINE static auto NthVectorElem(const T &vec, size_t n) ->
    typename VectorType<T>::BaseType {
  return vec[n];
}

// Access the Nth element of an aggregate vector.
#define MAKE_EXTRACTV(size, base_type, accessor, out, prefix) \
  template <typename T> \
  ALWAYS_INLINE static base_type prefix##ExtractV##size(const T &vec, \
                                                        size_t n) { \
    static_assert(sizeof(base_type) == sizeof(typename VectorType<T>::BT), \
                  "Invalid extract"); \
    return out(vec.elems[n]); \
  }

MAKE_EXTRACTV(8, uint8_t, bytes, Unsigned, U)
MAKE_EXTRACTV(16, uint16_t, words, Unsigned, U)
MAKE_EXTRACTV(32, uint32_t, dwords, Unsigned, U)
MAKE_EXTRACTV(64, uint64_t, qwords, Unsigned, U)
MAKE_EXTRACTV(128, uint128_t, dqwords, Unsigned, U)
MAKE_EXTRACTV(8, int8_t, bytes, Signed, S)
MAKE_EXTRACTV(16, int16_t, words, Signed, S)
MAKE_EXTRACTV(32, int32_t, dwords, Signed, S)
MAKE_EXTRACTV(64, int64_t, qwords, Signed, S)
MAKE_EXTRACTV(128, int128_t, dqwords, Signed, S)
MAKE_EXTRACTV(32, float32_t, floats, Identity, F)
MAKE_EXTRACTV(64, float64_t, doubles, Identity, F)
MAKE_EXTRACTV(80, float80_t, tdoubles, Identity, F)

#undef MAKE_EXTRACTV

ALWAYS_INLINE static int8_t SAbs(int8_t val) {
  return val < 0 ? -val : val;
}

ALWAYS_INLINE static int16_t SAbs(int16_t val) {
  return val < 0 ? -val : val;
}

ALWAYS_INLINE static int32_t SAbs(int32_t val) {
  return val < 0 ? -val : val;
}

ALWAYS_INLINE static int64_t SAbs(int64_t val) {
  return val < 0 ? -val : val;
}

template <typename T>
ALWAYS_INLINE static auto SAbs(typename IntegerType<T>::ST val) ->
    typename IntegerType<T>::ST {
  return Select(SLt(val, 0), SNeg(val), val);
}

template <typename T>
ALWAYS_INLINE static auto UAbs(typename IntegerType<T>::UT val) ->
    typename IntegerType<T>::UT {
  return val;
}

// Access the Nth element of an aggregate vector.
#define MAKE_INSERTV(prefix, size, base_type, accessor) \
  template <typename T> \
  ALWAYS_INLINE static T prefix##InsertV##size(T vec, size_t n, \
                                               base_type val) { \
    static_assert(sizeof(base_type) == sizeof(typename VectorType<T>::BT), \
                  "Invalid extract"); \
    vec.elems[n] = val; \
    return vec; \
  }

MAKE_INSERTV(U, 8, uint8_t, bytes)
MAKE_INSERTV(U, 16, uint16_t, words)
MAKE_INSERTV(U, 32, uint32_t, dwords)
MAKE_INSERTV(U, 64, uint64_t, qwords)
MAKE_INSERTV(U, 128, uint128_t, dqwords)

MAKE_INSERTV(S, 8, int8_t, sbytes)
MAKE_INSERTV(S, 16, int16_t, swords)
MAKE_INSERTV(S, 32, int32_t, sdwords)
MAKE_INSERTV(S, 64, int64_t, sqwords)
MAKE_INSERTV(S, 128, int128_t, sdqwords)

MAKE_INSERTV(F, 32, float32_t, floats)
MAKE_INSERTV(F, 64, float64_t, doubles)
MAKE_INSERTV(F, 80, float80_t, tdoubles)

#undef MAKE_INSERTV

// Update the Nth element of an aggregate vector.
#define MAKE_UPDATEV(prefix, size, base_type, accessor) \
  template <typename T> \
  ALWAYS_INLINE static void prefix##UpdateV##size(T &vec, size_t n, \
                                                  base_type val) { \
    static_assert(sizeof(base_type) == sizeof(typename VectorType<T>::BT), \
                  "Invalid update"); \
    vec.elems[n] = val; \
  }

MAKE_UPDATEV(U, 8, uint8_t, bytes)
MAKE_UPDATEV(U, 16, uint16_t, words)
MAKE_UPDATEV(U, 32, uint32_t, dwords)
MAKE_UPDATEV(U, 64, uint64_t, qwords)
MAKE_UPDATEV(U, 128, uint128_t, dqwords)

MAKE_UPDATEV(S, 8, int8_t, sbytes)
MAKE_UPDATEV(S, 16, int16_t, swords)
MAKE_UPDATEV(S, 32, int32_t, sdwords)
MAKE_UPDATEV(S, 64, int64_t, sqwords)
MAKE_UPDATEV(S, 128, int128_t, sdqwords)

MAKE_UPDATEV(F, 32, float32_t, floats)
MAKE_UPDATEV(F, 64, float64_t, doubles)
MAKE_UPDATEV(F, 80, float80_t, tdoubles)

#undef MAKE_UPDATEV

template <typename U, typename T>
ALWAYS_INLINE static constexpr T _ZeroVec(void) {
  static_assert(std::is_same<U, typename VectorType<T>::BT>::value,
                "Vector type and base don't match.");
  return {};
}

#define _ClearV(base_type, ...)

#define UClearV8(...) _ZeroVec<uint8_t, decltype(__VA_ARGS__)>()
#define UClearV16(...) _ZeroVec<uint16_t, decltype(__VA_ARGS__)>()
#define UClearV32(...) _ZeroVec<uint32_t, decltype(__VA_ARGS__)>()
#define UClearV64(...) _ZeroVec<uint64_t, decltype(__VA_ARGS__)>()
#define UClearV128(...) _ZeroVec<uint128_t, decltype(__VA_ARGS__)>()

#define SClearV8(...) _ZeroVec<int8_t, decltype(__VA_ARGS__)>()
#define SClearV16(...) _ZeroVec<int16_t, decltype(__VA_ARGS__)>()
#define SClearV32(...) _ZeroVec<int32_t, decltype(__VA_ARGS__)>()
#define SClearV64(...) _ZeroVec<int64_t, decltype(__VA_ARGS__)>()
#define SClearV128(...) _ZeroVec<int128_t, decltype(__VA_ARGS__)>()

#define FClearV32(...) _ZeroVec<float32_t, decltype(__VA_ARGS__)>()
#define FClearV64(...) _ZeroVec<float64_t, decltype(__VA_ARGS__)>()

// Something has gone terribly wrong and we need to stop because there is
// an error.
//
// TODO(pag): What happens if there's a signal handler? How should we
//            communicate the error class?
#define StopFailure() return __remill_error(state, Read(REG_PC), memory)

// Aesthetically pleasing names that hide the implicit small-step semantics
// of the memory pointer.
#define BarrierLoadLoad() \
  do { \
    memory = __remill_barrier_load_load(memory); \
  } while (false)

#define BarrierLoadStore() \
  do { \
    memory = __remill_barrier_load_store(memory); \
  } while (false)

#define BarrierStoreLoad() \
  do { \
    memory = __remill_barrier_store_load(memory); \
  } while (false)

#define BarrierStoreStore() \
  do { \
    memory = __remill_barrier_store_store(memory); \
  } while (false)

#ifdef REMILL_BARRIER_AS_NOP

// The 'compiler' barrier is generating inline assembly which is inconvenient for KLEE
// disable it if flag `REMILL_BARRIER_AS_NOP` is defined.
#  define BarrierReorder(...)
#  define BarrierUsedHere(...)

#else

// A 'compiler' barrier that prevents reordering of instructions across the
// barrier. A thorough explanation can be found here:
// http://preshing.com/20120625/memory-ordering-at-compile-time/
#  define BarrierReorder() \
    do { \
      __asm__ __volatile__("" ::: "memory"); \
    } while (false)

// A 'compiler' barrier that also forces a variable's value to be resident in
// memory at the current spot. This is a useful debugging aid, e.g. when you
// see `<optimized out>` in GDB, and really pessimizes optimizations.
//
// An entertaining explanation is here: https://youtu.be/nXaxk27zwlk?t=40m50s
#  define BarrierUsedHere(x) \
    do { \
      __asm__ __volatile__("" ::"m"(x) : "memory"); \
    } while (false)
#endif

// Make a predicate for querying the type of an operand.
#define MAKE_PRED(name, X, val) \
  template <typename T> \
  ALWAYS_INLINE static constexpr bool Is##name(X<T>) { \
    return val; \
  }

MAKE_PRED(Register, Rn, true)
MAKE_PRED(Register, RnW, true)
MAKE_PRED(Register, Vn, true)
MAKE_PRED(Register, VnW, true)
MAKE_PRED(Register, Mn, false)
MAKE_PRED(Register, MnW, false)
MAKE_PRED(Register, MVn, false)
MAKE_PRED(Register, MVnW, false)
MAKE_PRED(Register, In, false)

MAKE_PRED(Memory, Rn, false)
MAKE_PRED(Memory, RnW, false)
MAKE_PRED(Memory, Vn, false)
MAKE_PRED(Memory, VnW, false)
MAKE_PRED(Memory, Mn, true)
MAKE_PRED(Memory, MnW, true)
MAKE_PRED(Memory, MVn, true)
MAKE_PRED(Memory, MVnW, true)
MAKE_PRED(Memory, In, false)

MAKE_PRED(Immediate, Rn, false)
MAKE_PRED(Immediate, RnW, false)
MAKE_PRED(Immediate, Vn, false)
MAKE_PRED(Immediate, VnW, false)
MAKE_PRED(Immediate, Mn, false)
MAKE_PRED(Immediate, MnW, false)
MAKE_PRED(Immediate, MVn, false)
MAKE_PRED(Immediate, MVnW, false)
MAKE_PRED(Immediate, In, true)

#undef MAKE_PRED
#define MAKE_PRED(name, T, val) \
  ALWAYS_INLINE static constexpr bool Is##name(T) { \
    return val; \
  }

MAKE_PRED(Register, uint8_t, true)
MAKE_PRED(Register, uint16_t, true)
MAKE_PRED(Register, uint32_t, true)
MAKE_PRED(Register, uint64_t, true)

MAKE_PRED(Immediate, uint8_t, true)
MAKE_PRED(Immediate, uint16_t, true)
MAKE_PRED(Immediate, uint32_t, true)
MAKE_PRED(Immediate, uint64_t, true)

#undef MAKE_PRED

template <typename T>
ALWAYS_INLINE static Mn<T> GetElementPtr(Mn<T> addr, addr_t index) {
  return {addr.addr + (index * static_cast<addr_t>(sizeof(T)))};
}

template <typename T>
ALWAYS_INLINE static MVn<T> GetElementPtr(MVn<T> addr, addr_t index) {
  return {addr.addr + (index * static_cast<addr_t>(sizeof(T)))};
}

template <typename T>
ALWAYS_INLINE static MnW<T> GetElementPtr(MnW<T> addr, addr_t index) {
  return {addr.addr + (index * static_cast<addr_t>(sizeof(T)))};
}

template <typename T>
ALWAYS_INLINE static MVnW<T> GetElementPtr(MVnW<T> addr, addr_t index) {
  return {addr.addr + (index * static_cast<addr_t>(sizeof(T)))};
}

template <typename T>
ALWAYS_INLINE static auto ReadPtr(addr_t addr) -> Mn<typename BaseType<T>::BT> {
  return {addr};
}

template <typename T>
ALWAYS_INLINE static auto ReadPtr(addr_t addr, addr_t seg_base)
    -> Mn<typename BaseType<T>::BT> {
  return {addr + seg_base};
}

template <typename T>
ALWAYS_INLINE static auto WritePtr(addr_t addr)
    -> MnW<typename BaseType<T>::BT> {
  return {addr};
}

template <typename T>
ALWAYS_INLINE static auto WritePtr(addr_t addr, addr_t seg_base)
    -> MnW<typename BaseType<T>::BT> {
  return {addr + seg_base};
}

template <typename T>
ALWAYS_INLINE static auto VReadPtr(addr_t addr) -> MVn<T> {
  return {addr};
}

template <typename T>
ALWAYS_INLINE static auto VReadPtr(addr_t addr, addr_t seg_base) -> MVn<T> {
  return {addr + seg_base};
}

template <typename T>
ALWAYS_INLINE static auto VWritePtr(addr_t addr) -> MVnW<T> {
  return {addr};
}

template <typename T>
ALWAYS_INLINE static auto VWritePtr(addr_t addr, addr_t seg_base) -> MVnW<T> {
  return {addr + seg_base};
}

template <typename T>
ALWAYS_INLINE static addr_t AddressOf(Mn<T> addr) {
  return addr.addr;
}

template <typename T>
ALWAYS_INLINE static addr_t AddressOf(MnW<T> addr) {
  return addr.addr;
}

template <typename T>
ALWAYS_INLINE static addr_t AddressOf(MVn<T> addr) {
  return addr.addr;
}

template <typename T>
ALWAYS_INLINE static addr_t AddressOf(MVnW<T> addr) {
  return addr.addr;
}

template <typename T>
ALWAYS_INLINE static Mn<T> DisplaceAddress(Mn<T> addr, addr_t disp) {
  return Mn<T>{addr.addr + disp};
}

template <typename T>
ALWAYS_INLINE static MnW<T> DisplaceAddress(MnW<T> addr, addr_t disp) {
  return MnW<T>{addr.addr + disp};
}

template <typename T>
ALWAYS_INLINE static MVn<T> DisplaceAddress(MVn<T> addr, addr_t disp) {
  return MVn<T>{addr.addr + disp};
}

template <typename T>
ALWAYS_INLINE static MVnW<T> DisplaceAddress(MVnW<T> addr, addr_t disp) {
  return MVnW<T>{addr.addr + disp};
}

template <typename T>
ALWAYS_INLINE static T Select(bool cond, T if_true, T if_false) {
  return cond ? if_true : if_false;
}

#define BUndefined __remill_undefined_8
#define UUndefined8 __remill_undefined_8
#define UUndefined16 __remill_undefined_16
#define UUndefined32 __remill_undefined_32
#define UUndefined64 __remill_undefined_64

// TODO(pag): Assumes little-endian.
ALWAYS_INLINE static uint128_t __remill_read_memory_128(Memory *mem,
                                                        addr_t addr) {
  uint128_t low_qword = ZExt(__remill_read_memory_64(mem, addr));
  uint128_t high_qword = ZExt(__remill_read_memory_64(mem, addr + 8));
  return UOr(UShl(high_qword, 64), low_qword);
}

// TODO(pag): Assumes little-endian.
ALWAYS_INLINE static Memory *__remill_write_memory_128(Memory *mem, addr_t addr,
                                                       uint128_t val) {
  uint64_t low_qword = Trunc(val);
  uint64_t high_qword = Trunc(UShr(val, 64));
  mem = __remill_write_memory_64(mem, addr, low_qword);
  mem = __remill_write_memory_64(mem, addr + 8, high_qword);
  return mem;
}

// Issue #374: https://github.com/lifting-bits/remill/issues/374
//
// The builtins may have defined or undefined behavior given a zero, depending
// on the target arch.
#define MAKE_BUILTIN(name, size, input_size, builtin, disp) \
  ALWAYS_INLINE static uint##size##_t name(uint##size##_t val) { \
    const auto in_val = static_cast<uint##input_size##_t>(val); \
    return in_val ? (static_cast<uint##size##_t>(builtin(in_val)) - \
                     static_cast<uint##input_size##_t>(disp)) \
                  : size; \
  }

MAKE_BUILTIN(CountLeadingZeros, 8, 32, __builtin_clz, 24)
MAKE_BUILTIN(CountLeadingZeros, 16, 32, __builtin_clz, 16)
MAKE_BUILTIN(CountLeadingZeros, 32, 32, __builtin_clz, 0)
MAKE_BUILTIN(CountLeadingZeros, 64, 64, __builtin_clzll, 0)

MAKE_BUILTIN(CountTrailingZeros, 8, 32, __builtin_ctz, 0)
MAKE_BUILTIN(CountTrailingZeros, 16, 32, __builtin_ctz, 0)
MAKE_BUILTIN(CountTrailingZeros, 32, 32, __builtin_ctz, 0)
MAKE_BUILTIN(CountTrailingZeros, 64, 64, __builtin_ctzll, 0)

#undef MAKE_BUILTIN

#define MAKE_BUILTIN_INTRINSIC(name, intrinsic_name, size, type) \
  ALWAYS_INLINE static type name(type val) { \
    return intrinsic_name(val); \
  } \
  ALWAYS_INLINE static type name##size(type val) { \
    return intrinsic_name(val); \
  }

#if defined(__x86_64__) || defined(__i386__) || defined(_M_X86)
#define MAKE_BUILTIN(name, intrinsic_name) \
  MAKE_BUILTIN_INTRINSIC(name, intrinsic_name##f, 32, float32_t) \
  MAKE_BUILTIN_INTRINSIC(name, intrinsic_name, 64, float64_t) \
  MAKE_BUILTIN_INTRINSIC(name, intrinsic_name##l, 80, float80_t)
#else
#define MAKE_BUILTIN(name, intrinsic_name) \
  MAKE_BUILTIN_INTRINSIC(name, intrinsic_name##f, 32, float32_t) \
  MAKE_BUILTIN_INTRINSIC(name, intrinsic_name, 64, float64_t) \
  MAKE_BUILTIN_INTRINSIC(name, intrinsic_name, 80, float80_t)
#endif

MAKE_BUILTIN(FAbs, __builtin_fabs);
MAKE_BUILTIN(FCos, __builtin_cos)
MAKE_BUILTIN(FSin, __builtin_sin)
MAKE_BUILTIN(FTan, __builtin_tan)
MAKE_BUILTIN(FAtan,__builtin_atan)
MAKE_BUILTIN(FSqrt,__builtin_sqrt)
MAKE_BUILTIN(Exp2,__builtin_exp2)
MAKE_BUILTIN(Log2,__builtin_log2)

MAKE_BUILTIN(FRoundUsingMode, __builtin_nearbyint);
MAKE_BUILTIN(FTruncTowardZero, __builtin_trunc);
MAKE_BUILTIN(FRoundAwayFromZero, __builtin_round);
MAKE_BUILTIN(FRoundToPositiveInfinity, __builtin_ceil);
MAKE_BUILTIN(FRoundToNegativeInfinity, __builtin_floor);

#undef MAKE_BUILTIN_INTRINSIC
#undef MAKE_BUILTIN

ALWAYS_INLINE static int16_t Float64ToInt16(float64_t val) {
  auto max_int = Float64(Maximize(Int16(0)));
  return Select<int16_t>(FCmpLt(max_int, FAbs(val)), Int16(0x8000), Int16(val));
}

ALWAYS_INLINE static int32_t Float64ToInt32(float64_t val) {
  auto max_int = Float64(Maximize(Int32(0)));
  return Select<int32_t>(FCmpLt(max_int, FAbs(val)), Int32(0x80000000),
                         Int32(val));
}

ALWAYS_INLINE static int16_t Float80ToInt16(float80_t val) {
	auto max_int = Float80(Float64(Maximize(Int16(0))));
  return Select<int16_t>(FCmpLt80(max_int, FAbs80(val)), Int16(0x8000), Int16(val));
}

ALWAYS_INLINE static int32_t Float80ToInt32(float80_t val) {
  auto max_int = Float80(Float64(Maximize(Int32(0))));
  return Select<int32_t>(FCmpLt80(max_int, FAbs80(val)), Int32(0x80000000),
                         Int32(val));
}

ALWAYS_INLINE static int16_t Float32ToInt16(float32_t val) {
  auto max_int = Float32(Maximize(Int32(0)));
  return Select<int16_t>(FCmpLt(max_int, FAbs(val)), Int16(0x8000), Int16(val));
}

ALWAYS_INLINE static int32_t Float32ToInt32(float32_t val) {
  auto max_int = Float32(Maximize(Int32(0)));
  return Select<int32_t>(FCmpLt(max_int, FAbs(val)), Int32(0x80000000),
                         Int32(val));
}

ALWAYS_INLINE static int64_t Float32ToInt64(float32_t val) {
  return Int64(val);
}

ALWAYS_INLINE static int64_t Float64ToInt64(float64_t val) {
  auto max_int = Float64(Maximize(Int64(0)));
  return Select<int64_t>(FCmpLt(max_int, FAbs(val)),
                         Int64(0x8000000000000000LL), Int64(val));
}

ALWAYS_INLINE static int64_t Float80ToInt64(float80_t val) {
  auto max_int = Float80(Float64(Maximize(Int64(0))));
  return Select<int64_t>(FCmpLt80(max_int, FAbs80(val)),
                         Int64(0x8000000000000000LL), Int64(val));
}

ALWAYS_INLINE static float32_t FRoundToNearestEven32(float32_t val) {
  return FRoundUsingMode32(val);

  //  auto abs_val = __builtin_fabsf(val);
  //  auto sign = (val / abs_val);
  //  auto floor_val = __builtin_floorf(abs_val);
  //  auto ceil_val = __builtin_ceilf(abs_val);
  //  auto halfway_val = floor_val + 0.5;
  //  if (halfway_val == abs_val) {  // Half-way case.
  //    auto floor_val_int = Float32ToInt64(floor_val);
  //    if (floor_val_int % 2) {
  //      return ceil_val * sign;
  //    } else {
  //      return floor_val * sign;
  //    }
  //  } else {
  //    return __builtin_roundf(val);
  //  }
}

ALWAYS_INLINE static float64_t FRoundToNearestEven64(float64_t val) {
  return FRoundUsingMode64(val);

  //  auto abs_val = __builtin_fabs(val);
  //  auto sign = (val / abs_val);
  //  auto floor_val = __builtin_floor(abs_val);
  //  auto ceil_val = __builtin_ceil(abs_val);
  //  auto halfway_val = floor_val + 0.5;
  //  if (halfway_val == abs_val) {  // Half-way case.
  //    auto floor_val_int = Float64ToInt64(floor_val);
  //    if (floor_val_int % 2) {
  //      return ceil_val * sign;
  //    } else {
  //      return floor_val * sign;
  //    }
  //  } else {
  //    return __builtin_round(val);
  //  }
}

}  // namespace


text:
o.s

about

projects

contact

redpajama_set_name: RedPajamaGithub


text:
import unittest
from copy import deepcopy
from unittest.mock import patch

import responses
from werkzeug.exceptions import Forbidden

from config import TestingConfig
from frontstage import app
from frontstage.controllers import case_controller
from frontstage.exceptions.exceptions import (
    ApiError,
    InvalidCaseCategory,
    NoSurveyPermission,
)
from tests.integration.mocked_services import (
    business_party,
    case,
    case_list,
    case_list_with_iac_and_case_events,
    categories,
    collection_exercise,
    collection_instrument_seft,
    eq_payload,
    respondent_party,
    survey,
    survey_eq,
    url_get_case,
    url_get_case_by_enrolment_code,
    url_get_case_categories,
    url_get_cases_by_party,
    url_get_survey_by_short_name,
    url_get_survey_by_short_name_eq,
    url_post_case_event_uuid,
)

class TestCaseControllers(unittest.TestCase):
    def setUp(self):
        app_config = TestingConfig()
        app.config.from_object(app_config)
        self.app = app.test_client()
        self.app_config = self.app.application.config

    def test_calculate_case_status_returns_correct_status_for_complete_for_eq_and_seft(self):

        case_status_seft = case_controller.calculate_case_status("COMPLETE", "SEFT")
        case_status_eq = case_controller.calculate_case_status("COMPLETE", "EQ")

        self.assertEqual("Complete", case_status_seft)
        self.assertEqual("Complete", case_status_eq)

    def test_calculate_case_status_returns_correct_status_for_completed_by_phone_for_eq_and_seft(self):

        case_status_seft = case_controller.calculate_case_status("COMPLETEDBYPHONE", "SEFT")
        case_status_eq = case_controller.calculate_case_status("COMPLETEDBYPHONE", "EQ")

        self.assertEqual("Completed by phone", case_status_seft)
        self.assertEqual("Completed by phone", case_status_eq)

    def test_calculate_case_status_returns_correct_status_for_no_longer_required_for_eq_and_seft(self):

        case_status_seft = case_controller.calculate_case_status("NOLONGERREQUIRED", "SEFT")
        case_status_eq = case_controller.calculate_case_status("NOLONGERREQUIRED", "EQ")

        self.assertEqual("No longer required", case_status_seft)
        self.assertEqual("No longer required", case_status_eq)

    def test_calculate_case_status_returns_correct_state_for_in_progress_for_eq_and_seft(self):

        case_status_seft = case_controller.calculate_case_status("INPROGRESS", "SEFT")
        case_status_eq = case_controller.calculate_case_status("INPROGRESS", "EQ")

        self.assertEqual("Downloaded", case_status_seft)
        self.assertEqual("In progress", case_status_eq)

    def test_calculate_case_status_returns_not_started_with_unexpected_status(self):

        case_status_seft = case_controller.calculate_case_status("Apple", "SEFT")
        case_status_eq = case_controller.calculate_case_status("Banana", "EQ")

        self.assertEqual("Not started", case_status_seft)
        self.assertEqual("Not started", case_status_eq)

    def test_get_case_by_id_success(self):
        with responses.RequestsMock() as rsps:
            rsps.add(rsps.GET, url_get_case, json=case, status=200, content_type="application/json")
            with app.app_context():
                get_case = case_controller.get_case_by_case_id(case["id"])

                self.assertEqual(case["partyId"], get_case["partyId"])

    def test_get_case_by_id_fail(self):
        with responses.RequestsMock() as rsps:
            rsps.add(rsps.GET, url_get_case, status=400)
            with app.app_context():
                with self.assertRaises(ApiError):
                    case_controller.get_case_by_case_id(case["id"])

    def test_get_case_by_enrolment_code_success(self):
        with responses.RequestsMock() as rsps:
            rsps.add(rsps.GET, url_get_case_by_enrolment_code, json=case, status=200, content_type="application/json")
            with app.app_context():
                get_case = case_controller.get_case_by_enrolment_code(case["iac"])

                self.assertEqual(get_case["iac"], case["iac"])
                self.assertEqual(get_case["id"], case["id"])

    def test_get_case_by_enrolment_code_fail(self):
        with responses.RequestsMock() as rsps:
            rsps.add(rsps.GET, url_get_case_by_enrolment_code, status=400)
            with app.app_context():
                with self.assertRaises(ApiError):
                    case_controller.get_case_by_enrolment_code(case["iac"])

    def test_get_case_categories_success(self):
        with responses.RequestsMock() as rsps:
            rsps.add(rsps.GET, url_get_case_categories, json=categories, status=200, content_type="application/json")
            with app.app_context():
                get_categories = case_controller.get_case_categories()

                self.assertEqual(get_categories[0]["name"], categories[0]["name"])

    def test_get_case_categories_fail(self):
        with responses.RequestsMock() as rsps:
            rsps.add(rsps.GET, url_get_case_categories, status=400)
            with app.app_context():
                with self.assertRaises(ApiError):
                    self.assertRaises(ApiError, case_controller.get_case_categories())

    @patch("frontstage.controllers.party_controller.is_respondent_enrolled")
    @patch("frontstage.controllers.case_controller.post_case_event")
    @patch("frontstage.common.eq_payload.EqPayload.create_payload")
    @patch("frontstage.controllers.case_controller.get_case_by_case_id")
    def test_get_eq_url_case_group_status_not_complete(self, get_case_by_id, create_eq_payload, *_):
        get_case_by_id.return_value = case
        create_eq_payload.return_value = eq_payload
        with responses.RequestsMock() as rsps:
            rsps.add(rsps.GET, url_get_survey_by_short_name_eq, json=survey_eq, status=200)
            with app.app_context():
                eq_url = case_controller.get_eq_url(
                    "v2",
                    case,
                    collection_exercise,
                    respondent_party["id"],
                    business_party["id"],
                    survey_eq["shortName"],
                )

                self.assertIn("https://eq-test/session?token=", eq_url)

    @patch("frontstage.controllers.party_controller.is_respondent_enrolled")
    @patch("frontstage.controllers.case_controller.post_case_event")
    @patch("frontstage.common.eq_payload.EqPayload.create_payload")
    @patch("frontstage.controllers.case_controller.get_case_by_case_id")
    def test_get_eq_v3_url_case_group_status_not_complete(self, get_case_by_id, create_eq_payload, *_):
        get_case_by_id.return_value = case
        create_eq_payload.return_value = eq_payload
        with responses.RequestsMock() as rsps:
            rsps.add(rsps.GET, url_get_survey_by_short_name_eq, json=survey_eq, status=200)
            with app.app_context():
                eq_url = case_controller.get_eq_url(
                    "v3",
                    case,
                    collection_exercise,
                    respondent_party["id"],
                    business_party["id"],
                    survey_eq["shortName"],
                )

                self.assertIn("https://eq-test/v3/session?token=", eq_url)

    @patch("frontstage.controllers.party_controller.is_respondent_enrolled")
    @patch("frontstage.controllers.case_controller.post_case_event")
    @patch("frontstage.common.eq_payload.EqPayload.create_payload")
    @patch("frontstage.controllers.case_controller.get_case_by_case_id")
    def test_get_eq_url_blank_eq_version_redirects_to_v2(self, get_case_by_id, create_eq_payload, *_):
        get_case_by_id.return_value = case
        create_eq_payload.return_value = eq_payload
        with responses.RequestsMock() as rsps:
            rsps.add(rsps.GET, url_get_survey_by_short_name_eq, json=survey_eq, status=200)
            with app.app_context():
                eq_url = case_controller.get_eq_url(
                    None,
                    case,
                    collection_exercise,
                    respondent_party["id"],
                    business_party["id"],
                    survey_eq["shortName"],
                )

                self.assertIn("https://eq-test/session?token=", eq_url)

    @patch("frontstage.controllers.party_controller.is_respondent_enrolled")
    @patch("frontstage.controllers.case_controller.get_case_by_case_id")
    def test_get_eq_url_when_caseGroupStatus_is_complete(self, get_case_by_id, _):
        case_copy = deepcopy(case)
        case_copy["caseGroup"]["caseGroupStatus"] = "COMPLETE"
        get_case_by_id.return_value = case_copy
        with app.app_context():
            with self.assertRaises(Forbidden):
                case_controller.get_eq_url(
                    "v2",
                    case_copy,
                    collection_exercise,
                    respondent_party["id"],
                    business_party["id"],
                    survey_eq["shortName"],
                )

    @patch("frontstage.controllers.party_controller.is_respondent_enrolled")
    @patch("frontstage.controllers.case_controller.get_case_by_case_id")
    def test_get_eq_url_when_caseGroupStatus_is_completed_by_phone(self, get_case_by_id, _):
        case_copy = deepcopy(case)
        case_copy["caseGroup"]["caseGroupStatus"] = "COMPLETEDBYPHONE"
        get_case_by_id.return_value = case_copy
        with app.app_context():
            with self.assertRaises(Forbidden):
                case_controller.get_eq_url(
                    "v2",
                    case_copy,
                    collection_exercise,
                    respondent_party["id"],
                    business_party["id"],
                    survey_eq["shortName"],
                )

    @patch("frontstage.controllers.party_controller.is_respondent_enrolled")
    @patch("frontstage.controllers.case_controller.get_case_by_case_id")
    def test_get_eq_url_when_caseGroupStatus_is_no_longer_required(self, get_case_by_id, _):
        case_copy = deepcopy(case)
        case_copy["caseGroup"]["caseGroupStatus"] = "NOLONGERREQUIRED"
        get_case_by_id.return_value = case_copy
        with app.app_context():
            with self.assertRaises(Forbidden):
                case_controller.get_eq_url(
                    "v2",
                    case_copy,
                    collection_exercise,
                    respondent_party["id"],
                    business_party["id"],
                    survey_eq["shortName"],
                )

    @patch("frontstage.controllers.case_controller.get_case_by_case_id")
    @patch("frontstage.controllers.party_controller.is_respondent_enrolled")
    def test_get_eq_url_no_survey_permission(self, is_respondent_enrolled, get_case_by_id):
        is_respondent_enrolled.return_value = False
        get_case_by_id.return_value = case

        with responses.RequestsMock() as rsps:
            rsps.add(rsps.GET, url_get_survey_by_short_name_eq, json=survey_eq, status=200)
            with app.app_context():
                with self.assertRaises(NoSurveyPermission):
                    case_controller.get_eq_url(
                        "v2",
                        case,
                        collection_exercise,
                        respondent_party["id"],
                        business_party["id"],
                        survey_eq["shortName"],
                    )

    def test_get_eq_url_unsupported_version(self):
        with app.app_context():
            with self.assertRaises(ValueError) as e:
                case_controller.get_eq_url(
                    "v1234",
                    case,
                    collection_exercise,
                    respondent_party["id"],
                    business_party["id"],
                    survey_eq["shortName"],
                )

            self.assertEqual(str(e.exception), "The eq version [v1234] is not supported")

    @patch("frontstage.controllers.case_controller.validate_case_category")
    def test_post_case_event_success(self, _):
        message = {
            "description": "Access code authentication attempted'",
            "category": "ACCESS_CODE_AUTHENTICATION_ATTEMPT",
            "partyId": respondent_party["id"],
            "createdBy": "RAS_FRONTSTAGE",
        }
        with responses.RequestsMock() as rsps:
            rsps.add(rsps.POST, url_post_case_event_uuid, json=message, status=200)
            with app.app_context():
                try:
                    case_controller.post_case_event(
                        case["id"], respondent_party["id"], message["category"], message["description"]
                    )
                except ApiError:
                    self.fail("Unexpected ApiError thrown when posting case event")

    @patch("frontstage.controllers.case_controller.validate_case_category")
    def test_post_case_event_fail(self, _):
        message = {
            "description": "Access code authentication attempted'",
            "category": "ACCESS_CODE_AUTHENTICATION_ATTEMPT",
            "partyId": respondent_party["id"],
            "createdBy": "RAS_FRONTSTAGE",
        }
        with responses.RequestsMock() as rsps:
            rsps.add(rsps.POST, url_post_case_event_uuid, json=message, status=400)
            with app.app_context():
                with self.assertRaises(ApiError):
                    case_controller.post_case_event(
                        case["id"], respondent_party["id"], message["category"], message["description"]
                    )

    @patch("frontstage.controllers.case_controller.get_case_categories")
    def test_validate_case_category_valid_category(self, get_case_event_categories):
        get_case_event_categories.return_value = categories

        try:
            case_controller.validate_case_category(categories[0]["name"])
        except InvalidCaseCategory:
            self.fail("Unexpected validation fail for case category")

    @patch("frontstage.controllers.case_controller.get_case_categories")
    def test_validate_case_category_invalid_category(self, get_case_event_categories):
        get_case_event_categories.return_value = categories

        with self.assertRaises(InvalidCaseCategory):
            case_controller.validate_case_category("Banana")

    @patch("frontstage.controllers.case_controller.get_cases_by_party_id")
    def test_get_cases_for_list_type_by_party_id_todo(self, get_cases_by_party_id):
        get_cases_by_party_id.return_value = case_list

        cases = case_controller.get_cases_for_list_type_by_party_id(
            respondent_party["id"], self.app_config["CASE_URL"], self.app_config["BASIC_AUTH"]
        )
        for business_case in cases:
            for status in ["COMPLETE", "COMPLETEDBYPHONE", "NOLONGERREQUIRED"]:
                self.assertNotIn(business_case["caseGroup"]["caseGroupStatus"], status)

    @patch("frontstage.controllers.case_controller.get_cases_by_party_id")
    def test_get_cases_for_list_type_by_party_id_history(self, get_cases_by_party_id):
        get_cases_by_party_id.return_value = case_list

        cases = case_controller.get_cases_for_list_type_by_party_id(
            respondent_party["id"], self.app_config["CASE_URL"], self.app_config["BASIC_AUTH"], list_type="history"
        )

        for business_case in cases:
            for status in ["INPROGRESS", "NOTSTARTED", "REOPENED"]:
                self.assertNotIn(business_case["caseGroup"]["caseGroupStatus"], status)

    @patch("frontstage.controllers.party_controller.is_respondent_enrolled")
    @patch("frontstage.controllers.case_controller.get_case_by_case_id")
    @patch("frontstage.controllers.party_controller.get_party_by_business_id")
    @patch("frontstage.controllers.survey_controller.get_survey_by_short_name")
    @patch("frontstage.controllers.collection_instrument_controller.get_collection_instrument")
    @patch("frontstage.controllers.collection_exercise_controller.get_collection_exercise")
    def test_get_case_data_success(
        self,
        get_collection_exercise,
        get_collection_instrument,
        get_survey_by_short_name,
        get_party_by_business_id,
        get_case,
        _,
    ):

        get_collection_exercise.return_value = collection_exercise
        get_collection_instrument.return_value = collection_instrument_seft
        get_survey_by_short_name.return_value = survey
        get_party_by_business_id.return_value = business_party
        get_case.return_value = case

        with app.app_context():
            case_data = case_controller.get_case_data(
                case["id"], respondent_party["id"], business_party["id"], survey["shortName"]
            )

            self.assertEqual(collection_exercise["id"], case_data["collection_exercise"]["id"])
            self.assertEqual(collection_instrument_seft["id"], case_data["collection_instrument"]["id"])
            self.assertEqual(survey["shortName"], case_data["survey"]["shortName"])
            self.assertEqual(business_party["id"], case_data["business_party"]["id"])

    @patch("frontstage.controllers.party_controller.is_respondent_enrolled")
    @patch("frontstage.controllers.case_controller.get_case_by_case_id")
    def test_get_case_data_no_survey_permission(self, get_case_by_id, is_respondent_enrolled):
        get_case_by_id.return_value = case
        is_respondent_enrolled.return_value = False

        with responses.RequestsMock() as rsps:
            rsps.add(rsps.GET, url_get_survey_by_short_name, json=survey, status=200)
            with app.app_context():
                with self.assertRaises(NoSurveyPermission):
                    case_controller.get_case_data(
                        case["id"], respondent_party["id"], business_party["id"], survey["shortName"]
                    )

    def test_get_cases_by_party_id_with_case_events(self):
        with responses.RequestsMock() as rsps:
            url = f"{url_get_cases_by_party}?caseevents=true"
            rsps.add(rsps.GET, url, json=case_list, status=200)
            with app.app_context():
                returned_cases = case_controller.get_cases_by_party_id(
                    case["partyId"], self.app_config["CASE_URL"], self.app_config["BASIC_AUTH"], case_events=True
                )

                self.assertNotEqual(len(returned_cases), 0)

    def test_get_cases_by_party_id_without_case_events(self):
        with responses.RequestsMock() as rsps:
            rsps.add(rsps.GET, url_get_cases_by_party, json=case_list, status=200)
            with app.app_context():
                returned_cases = case_controller.get_cases_by_party_id(
                    case["partyId"], self.app_config["CASE_URL"], self.app_config["BASIC_AUTH"]
                )

                self.assertNotEqual(len(returned_cases), 0)

    def test_get_cases_by_party_id_without_iac(self):
        with responses.RequestsMock() as rsps:
            rsps.add(rsps.GET, url_get_cases_by_party, json=case_list, status=200)
            with app.app_context():
                returned_cases = case_controller.get_cases_by_party_id(
                    case["partyId"], self.app_config["CASE_URL"], self.app_config["BASIC_AUTH"], iac=False
                )

                self.assertNotEqual(len(returned_cases), 0)
                self.assertIsNone(returned_cases[0]["iac"])

    def test_get_cases_by_party_id_without_iac_and_with_case_events(self):
        with responses.RequestsMock() as rsps:
            rsps.add(rsps.GET, url_get_cases_by_party, json=case_list_with_iac_and_case_events, status=200)
            with app.app_context():
                returned_cases = case_controller.get_cases_by_party_id(
                    case["partyId"],
                    self.app_config["CASE_URL"],
                    self.app_config["BASIC_AUTH"],
                    iac=False,
                    case_events=True,
                )

                self.assertNotEqual(len(returned_cases), 0)
                self.assertIsNone(returned_cases[0]["iac"])
                self.assertIsNotNone(returned_cases[0]["caseEvents"][0])

    def test_get_cases_by_party_id_fail(self):
        with responses.RequestsMock() as rsps:
            rsps.add(rsps.GET, url_get_cases_by_party, status=400)
            with app.app_context():
                with self.assertRaises(ApiError):
                    case_controller.get_cases_by_party_id(
                        case["partyId"], self.app_config["CASE_URL"], self.app_config["BASIC_AUTH"]
                    )


text:
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Analysis;

/**
 * ***************************************************************
 * This program was written by Dr. Benny Raphael. The purpose of this program is
 * only to demonstrate some concepts discussed in the book "Fundamentals of
 * Computer Aided Engineering" by Benny Raphael and Ian F. C. Smith, John Wiley,
 * UK, 2003.
 * (http://www.wiley.com/WileyCDA/WileyTitle/productCd-0471487155.html) The
 * author (Benny Raphael) grants everyone permission to copy and use this code
 * freely provided that a) this copyright notice is not modified b) Any change
 * to this code is clearly indicated c) the user takes complete responsibility
 * for the use, misuse or non-use of this code. No care has been made to ensure
 * that the implementation is efficient, or entirely accurate with respect to
 * the concept that is demonstrated.
******************************************************************
 */
import java.io.*;
import java.util.*;

/**
 * A simple implementation of the id3 algorithm This is a modified version to
 * make my code closer to the standard id3 algorithm
 *
 * @version Dec. 13 2004
 * @author Dr. Benny Raphael
 *
 */
public class id3 {

    public int numAttributes;              // The number of attributes including the output attribute
    public String[] attributeNames;        // The names of all attributes.  It is an array of dimension numAttributes.  The last attribute is the output attribute
    public int atributoClase;
    /* Possible values for each attribute is stored in a vector.  domains is an array of dimension numAttributes.
     Each element of this array is a vector that contains values for the corresponding attribute
     domains[0] is a vector containing the values of the 0-th attribute, etc..
     The last attribute is the output attribute
     */
    public Vector[] domains;

    /*  The root of the decomposition tree  */
    TreeNode root = new TreeNode();

    /*  This function returns an integer corresponding to the symbolic value of the attribute.
     If the symbol does not exist in the domain, the symbol is added to the domain of the attribute
     */
    private int getSymbolValue(int attribute, String symbol) {
        int index = domains[attribute].indexOf(symbol);
        if (index < 0) {
            domains[attribute].addElement(symbol);
            return domains[attribute].size() - 1;
        }
        return index;
    }

    /*  Returns all the values of the specified attribute in the data set  */
    public int[] getAllValues(Vector data, int attribute) {
        Vector values = new Vector();
        int num = data.size();
        for (int i = 0; i < num; i++) {
            DataPoint point = (DataPoint) data.elementAt(i);
            String symbol = (String) domains[attribute].elementAt(point.attributes[attribute]);
            int index = values.indexOf(symbol);
            if (index < 0) {
                values.addElement(symbol);
            }
        }

        int[] array = new int[values.size()];
        for (int i = 0; i < array.length; i++) {
            String symbol = (String) values.elementAt(i);
            array[i] = domains[attribute].indexOf(symbol);
        }
        values = null;
        return array;
    }

    /*  Returns a subset of data, in which the value of the specfied attribute of all data points is the specified value  */
    private Vector getSubset(Vector data, int attribute, int value) {
        Vector subset = new Vector();

        int num = data.size();
        for (int i = 0; i < num; i++) {
            DataPoint point = (DataPoint) data.elementAt(i);
            if (point.attributes[attribute] == value) {
                subset.addElement(point);
            }
        }
        return subset;

    }

    /*  Calculates the entropy of the set of data points.
     The entropy is calculated using the values of the output attribute which is the last element in the array attribtues
     */
    private double calculateEntropy(Vector data) {

        int numdata = data.size();
        if (numdata == 0) {
            return 0;
        }

        int attribute = atributoClase;
        int numvalues = domains[attribute].size();
        double sum = 0;
        for (int i = 0; i < numvalues; i++) {
            int count = 0;
            for (int j = 0; j < numdata; j++) {
                DataPoint point = (DataPoint) data.elementAt(j);
                if (point.attributes[attribute] == i) {
                    count++;
                }
            }
            double probability = 1. * count / numdata;
            if (count > 0) {
                sum += -probability * Math.log(probability);
            }
        }
        return sum;

    }

    /*  This function checks if the specified attribute is used to decompose the data set
     in any of the parents of the specfied node in the decomposition tree.
     Recursively checks the specified node as well as all parents
     */
    private boolean alreadyUsedToDecompose(TreeNode node, int attribute) {
        if (node.children != null) {
            if (node.decompositionAttribute == attribute) {
                return true;
            }
        }
        if (node.parent == null) {
            return false;
        }
        return alreadyUsedToDecompose(node.parent, attribute);
    }

    /*  This function decomposes the specified node according to the id3 algorithm.
     Recursively divides all children nodes until it is not possible to divide any further
     I have changed this code from my earlier version. I believe that the code
     in my earlier version prevents useless decomposition and results in a better decision tree!
     This is a more faithful implementation of the standard id3 algorithm
     */
    public void decomposeNode(TreeNode node) {

        double bestEntropy = 0;
        boolean selected = false;
        int selectedAttribute = 0;

        int numdata = node.data.size();
        int numinputattributes = numAttributes - 1;
        node.entropy = calculateEntropy(node.data);
        if (node.entropy == 0) {
            return;
        }

        /*  In the following two loops, the best attribute is located which
         causes maximum decrease in entropy
         */
        for (int i = 0; i < numinputattributes; i++) {

            if (atributoClase == i) {
                continue;
            }

            int numvalues = domains[i].size();
            if (alreadyUsedToDecompose(node, i)) {
                continue;
            }
            // Use the following variable to store the entropy for the test node created with the attribute i
            double averageentropy = 0;
            for (int j = 0; j < numvalues; j++) {
                Vector subset = getSubset(node.data, i, j);
                if (subset.size() == 0) {
                    continue;
                }
                double subentropy = calculateEntropy(subset);
                averageentropy += subentropy * subset.size();  // Weighted sum
            }

            averageentropy = averageentropy / numdata;   // Taking the weighted average
            if (selected == false) {
                selected = true;
                bestEntropy = averageentropy;
                selectedAttribute = i;
            } else {
                if (averageentropy < bestEntropy) {
                    selected = true;
                    bestEntropy = averageentropy;
                    selectedAttribute = i;
                }
            }

        }

        if (selected == false) {
            return;
        }

        // Now divide the dataset using the selected attribute
        int numvalues = domains[selectedAttribute].size();
        node.decompositionAttribute = selectedAttribute;
        node.children = new TreeNode[numvalues];
        for (int j = 0; j < numvalues; j++) {
            node.children[j] = new TreeNode();
            node.children[j].parent = node;
            node.children[j].data = getSubset(node.data, selectedAttribute, j);
            node.children[j].decompositionValue = j;
        }

        // Recursively divides children nodes
        for (int j = 0; j < numvalues; j++) {
            decomposeNode(node.children[j]);
        }

        // There is no more any need to keep the original vector.  Release this memory
        node.data = null;               // Let the garbage collector recover this memory

    }

    /**
     * Function to read the data file. The first line of the data file should
     * contain the names of all attributes. The number of attributes is inferred
     * from the number of words in this line. The last word is taken as the name
     * of the output attribute. Each subsequent line contains the values of
     * attributes for a data point. If any line starts with // it is taken as a
     * comment and ignored. Blank lines are also ignored.
     */
    public int readData(String filename) throws Exception {

        FileInputStream in = null;

        try {
            File inputFile = new File(filename);
            in = new FileInputStream(inputFile);
        } catch (Exception e) {
            System.err.println("Unable to open data file: " + filename + "\n" + e);
            return 0;
        }

        BufferedReader bin = new BufferedReader(new InputStreamReader(in));

        String input;
        while (true) {
            input = bin.readLine();
            if (input == null) {
                System.err.println("No data found in the data file: " + filename + "\n");
                return 0;
            }
            if (input.startsWith("//")) {
                continue;
            }
            if (input.equals("")) {
                continue;
            }
            break;
        }

        StringTokenizer tokenizer = new StringTokenizer(input);
        numAttributes = tokenizer.countTokens();
        if (numAttributes <= 1) {
            System.err.println("Read line: " + input);
            System.err.println("Could not obtain the names of attributes in the line");
            System.err.println("Expecting at least one input attribute and one output attribute");
            return 0;
        }

        domains = new Vector[numAttributes];
        for (int i = 0; i < numAttributes; i++) {
            domains[i] = new Vector();
        }
        attributeNames = new String[numAttributes];

        for (int i = 0; i < numAttributes; i++) {
            attributeNames[i] = tokenizer.nextToken();
        }

        while (true) {
            input = bin.readLine();
            if (input == null) {
                break;
            }
            if (input.startsWith("//")) {
                continue;
            }
            if (input.equals("")) {
                continue;
            }

            tokenizer = new StringTokenizer(input);
            int numtokens = tokenizer.countTokens();
            if (numtokens != numAttributes) {
                System.err.println("Read " + root.data.size() + " data");
                System.err.println("Last line read: " + input);
                System.err.println("Expecting " + numAttributes + " attributes");
                return 0;
            }

            DataPoint point = new DataPoint(numAttributes);
            for (int i = 0; i < numAttributes; i++) {
                point.attributes[i] = getSymbolValue(i, tokenizer.nextToken());
            }
            root.data.addElement(point);

        }

        bin.close();

        return 1;

    }       // End of function readData
    //-----------------------------------------------------------------------

    /*  This function prints the decision tree in the form of rules.
     The action part of the rule is of the form
     outputAttribute = "symbolicValue"
     or
     outputAttribute = { "Value1", "Value2", ..  }
     The second form is printed if the node cannot be decomposed any further into an homogenous set
     */
    public void printTree(TreeNode node, String tab) {

        int outputattr = atributoClase;

        if (node.children == null) {
            int[] values = getAllValues(node.data, outputattr);
            if (values.length == 1) {
                System.out.println(tab + "\t" + attributeNames[outputattr] + " = \"" + domains[outputattr].elementAt(values[0]) + "\";");
                return;
            }
            System.out.print(tab + "\t" + attributeNames[outputattr] + " = {");
            for (int i = 0; i < values.length; i++) {
                System.out.print("\"" + domains[outputattr].elementAt(values[i]) + "\" ");
                if (i != values.length - 1) {
                    System.out.print(" , ");
                }
            }
            System.out.println(" };");
            return;
        }

        int numvalues = node.children.length;
        for (int i = 0; i < numvalues; i++) {
            System.out.println(tab + "if( " + attributeNames[node.decompositionAttribute] + " == \""
                    + domains[node.decompositionAttribute].elementAt(i) + "\") {");
            printTree(node.children[i], tab + "\t");
            if (i != numvalues - 1) {
                System.out.print(tab + "} else ");
            } else {
                System.out.println(tab + "}");
            }
        }

    }

    /*  This function creates the decision tree and prints it in the form of rules on the console
     */
    public void createDecisionTree() {
        decomposeNode(root);
        //printTree(root, "");
    }

    /* Here is the definition of the main function */
    public static void main(String[] args) throws Exception {

        id3 me = new id3();

        Scanner in = new Scanner(System.in);

        System.out.print("Ruta del archivo: ");
        String str = in.nextLine();

        System.out.print("atrib Clase: ");
        me.atributoClase = in.nextInt();

        int status = me.readData(str);
        if (status <= 0) {
            return;
        }

        me.createDecisionTree();
    }
}


text:
mylisp
======

最初から最後までカッコたっぷり

永遠に不安定版

License
-------

This software is released under the MIT License, see LICENSE.


text:
[![Version](https://img.shields.io/cocoapods/v/CCLColorTransformer.svg?style=flat)](http://cocoadocs.org/docsets/CCLColorTransformer)
[![License](https://img.shields.io/cocoapods/l/CCLColorTransformer.svg?style=flat)](http://cocoadocs.org/docsets/CCLColorTransformer)
[![Platform](https://img.shields.io/cocoapods/p/CCLColorTransformer.svg?style=flat)](http://cocoadocs.org/docsets/CCLColorTransformer)

CCLColorTransformer is a simple NSValueTransformer to transform a color.

## Installation

CCLColorTransformer is available through [CocoaPods](http://cocoapods.org). To install
it, simply add the following line to your Podfile:

    pod "CCLColorTransformer"

## Author

Kyle Fuller, inbox@kylefuller.co.uk

## License

CCLColorTransformer is available under the MIT license. See the LICENSE file for more info.


text:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:layout_width="fill_parent"
              android:layout_height="wrap_content"
              android:orientation="vertical" >

    <!-- Product id (pid) - will be HIDDEN - used to pass to other activity -->
    <TextView
        android:id="@+id/pid"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:visibility="gone" />

    <!-- Name Label -->
    <TextView
        android:id="@+id/name"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:paddingTop="6dip"
        android:paddingLeft="6dip"
        android:textSize="17dip"
        android:textStyle="bold" />

</LinearLayout>


text:
module Repossessed
  class Config
    attr_accessor :allowed_keys, :find_keys, :serializable_keys
    attr_reader :block, :validations, :after_saves, :built, :mixins

    def initialize(persistence_class=nil, &block)
      @persistence_class =  convert_to_class(persistence_class)

      # default classes
      @parser_class =         Parser
      @validator_class =      Validator
      @repo_class =           Repo
      @serializer_class =     Serializer

      # default configuration values
      @validations = []
      @after_saves = []

      @block = block
    end

    [:persistence_class, :parser_class, :validator_class, :repo_class, :serializer_class].each do |class_type|
      class_eval <<-RUBY
        def #{class_type} val=nil
          getter_setter(:#{class_type}, val)
        end
      RUBY
    end

    def getter_setter(name, var=nil)
      if var
        var = convert_to_class(var)
        instance_variable_set("@#{name}", var)
      else
        instance_variable_get("@#{name}")
      end
    end

    def permit *keys
      self.allowed_keys = keys
    end

    alias :allow :permit

    def find_by *keys
      self.find_keys = keys
    end

    def serialize *keys
      self.serializable_keys = keys
    end

    # configuration of validations, same API as validator
    def ensure(*args, &block)
      validation = {args: args}
      validation[:block] = block if block
      validations << validation
    end

    alias :validate :ensure

    # configuring hooks in the coordinator
    def after_save(&block)
      after_saves << block
    end

    def build
      @built = false
      build_with_block if block
      self.serializable_keys ||= allowed_keys
      @built = true
      self
    end

    def mixin(&block)
      @mixins = block
    end

    def build_with_block
      instance_eval &block
    end

    def valid?
      errors.empty?
    end

    def errors
      if !built
        {config: 'not yet built'}
      else
        {}
          .merge(persistence_class_errors)
          .merge(allowed_keys_errors)
      end
    end

    # repo class is custom or it must be configured
    def persistence_class_errors
      return {} if persistence_class || repo_class != Repo
      {
        persistence_class: 'persistence_class must be set'
      }
    end

    # parser class is custom, or the keys much be in configuration
    def allowed_keys_errors
      return {} if parser_class != Parser || ( allowed_keys && allowed_keys.is_a?(Array) )
      {
        allowed_keys: 'allowed keys must be set to an array of values'
      }
    end

    def self.build(persistence_class=nil, &block)
      new(persistence_class, &block).build
    end

    private

    def convert_to_class(thing)
      return thing if thing.is_a?(Class)
      ActiveSupport::Inflector.constantize(thing)
    end
  end
end


text:
layout: page
title: blockFUNK Podcast
permalink: /blockfunk/
---


text:
package org.kuali.kra.award;

import org.kuali.kra.award.document.AwardDocument;
import org.kuali.kra.award.home.Award;
import org.kuali.kra.award.home.approvedsubawards.AwardApprovedSubaward;
import org.kuali.kra.infrastructure.Constants;
import org.kuali.kra.infrastructure.KeyConstants;
import org.kuali.rice.core.api.util.type.KualiDecimal;
import org.kuali.rice.kns.util.AuditCluster;
import org.kuali.rice.kns.util.AuditError;
import org.kuali.rice.kns.util.KNSGlobalVariables;
import org.kuali.rice.krad.document.Document;
import org.kuali.rice.krad.rules.rule.DocumentAuditRule;

import java.util.ArrayList;
import java.util.List;

/**
 * This class...
 */
public class AwardSubawardAuditRule implements DocumentAuditRule {

    private static final String SUBAWARD_AUDIT_ERRORS = "subawardAuditErrors";
    private static final String SUBAWARD_AUDIT_WARNINGS = "subawardAuditWarnings";

    List<AwardApprovedSubaward> awardApprovedSubawards;
    private List<AuditError> auditErrors;
    private List<AuditError> auditWarnings;

    /**
     * @see org.kuali.rice.krad.rules.rule.DocumentAuditRule#processRunAuditBusinessRules(org.kuali.rice.krad.document.Document)
     */
    public boolean processRunAuditBusinessRules(Document document) {
        boolean valid = true;
        AwardDocument awardDocument = (AwardDocument) document;
        auditErrors = new ArrayList<AuditError>();
        auditWarnings = new ArrayList<AuditError>();
        Award award = awardDocument.getAward();
        this.awardApprovedSubawards = award.getAwardApprovedSubawards();
        if(!validateApprovedSubawardDuplicateOrganization(awardApprovedSubawards)){
            valid = false;
            auditErrors.add(new AuditError(Constants.SUBAWARD_AUDIT_RULES_ERROR_KEY,
                    KeyConstants.ERROR_DUPLICATE_ORGANIZATION_NAME,
                    Constants.MAPPING_AWARD_HOME_PAGE + "." + Constants.SUBAWARD_PANEL_ANCHOR,
                    new String[]{"Organization"}));
        }
        for (int i = 0; i < awardApprovedSubawards.size(); i++) {
            AwardApprovedSubaward subAward = awardApprovedSubawards.get(i);
            KualiDecimal amount = subAward.getAmount();
            if (amount == null) {
                valid = false;  // a "required field" error is already reported by the framework, so don't call reportError
            } else if(!amount.isGreaterThan(new KualiDecimal(0.00))) {
                valid = false;
                auditWarnings.add(new AuditError("document.awardList[0].awardApprovedSubawards[" + i + "].amount",
                        KeyConstants.ERROR_AMOUNT_IS_ZERO,
                        Constants.MAPPING_AWARD_HOME_PAGE + "." + Constants.SUBAWARD_PANEL_ANCHOR,
                        null));
            }
        }
        reportAndCreateAuditCluster();
        return valid;
    }

    /**
     * This method creates and adds the AuditCluster to the Global AuditErrorMap.
     */
    @SuppressWarnings("unchecked")
    protected void reportAndCreateAuditCluster() {
        if (auditErrors.size() > 0) {
            KNSGlobalVariables.getAuditErrorMap().put(SUBAWARD_AUDIT_ERRORS, new AuditCluster(Constants.SUBAWARD_PANEL_NAME,
                                                                                auditErrors, Constants.AUDIT_ERRORS));
        }
        if (auditWarnings.size() > 0) {
            KNSGlobalVariables.getAuditErrorMap().put(SUBAWARD_AUDIT_WARNINGS, new AuditCluster(Constants.SUBAWARD_PANEL_NAME,
                    auditWarnings, Constants.AUDIT_WARNINGS));
        }
    }

    /**
    *
    * Test Approved Subawards for duplicate organizations
    * @return Boolean
    */
    protected boolean validateApprovedSubawardDuplicateOrganization(List<AwardApprovedSubaward> awardApprovedSubawards){
            boolean valid = true;
            int index = 0;
        test:
            for (AwardApprovedSubaward loopAwardApprovedSubaward : awardApprovedSubawards) {
                int innerIndex = 0;
                for(AwardApprovedSubaward testAwardApprovedSubaward : awardApprovedSubawards) {
                    if (innerIndex != index) {
                        if(testAwardApprovedSubaward.getOrganizationName().equals(loopAwardApprovedSubaward.getOrganizationName())){
                            valid = false;
                            break test;
                        }
                        innerIndex++;
                    }
                }
                index++;
            }
            return valid;
    }

}


text:
package com.navercorp.pinpoint.plugin.fastjson.interceptor;

import com.navercorp.pinpoint.bootstrap.context.MethodDescriptor;
import com.navercorp.pinpoint.bootstrap.context.SpanEventRecorder;
import com.navercorp.pinpoint.bootstrap.context.Trace;
import com.navercorp.pinpoint.bootstrap.context.TraceContext;
import com.navercorp.pinpoint.plugin.fastjson.FastjsonConstants;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;

import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.verify;

@ExtendWith(MockitoExtension.class)
public class ToJsonStringInterceptorTest {

    @Mock
    private TraceContext traceContext;

    @Mock
    private MethodDescriptor descriptor;

    @Mock
    private Trace trace;

    @Mock
    private SpanEventRecorder recorder;

    @Test
    public void before() {

        doReturn(trace).when(traceContext).currentTraceObject();
        doReturn(recorder).when(trace).traceBlockBegin();

        ToJsonStringInterceptor interceptor = new ToJsonStringInterceptor(traceContext, descriptor);

        interceptor.before(null, null);
    }

    @Test
    public void after() {

        doReturn(trace).when(traceContext).currentTraceObject();
        doReturn(recorder).when(trace).currentSpanEventRecorder();

        ToJsonStringInterceptor interceptor = new ToJsonStringInterceptor(traceContext, descriptor);

        interceptor.after(null, new Object[]{}, "{\"firstName\": \"Json\"}", null);

        verify(recorder).recordServiceType(FastjsonConstants.SERVICE_TYPE);
        verify(recorder).recordAttribute(FastjsonConstants.ANNOTATION_KEY_JSON_LENGTH, "{\"firstName\": \"Json\"}".length());
    }
}


text:
@import "/assets/css/bootstrap.min.css";
@import url('../node_modules/font-awesome/css/font-awesome.min.css');


text:
.zci--regexp .record .record__cell--key {
    width: 20em;
    text-transform: none;
}