// foldExpr.cpp — Phase 2.7 cxxSmoke check 5.
//
// Exercises C++17 fold expressions.  Three flavours, all in one TU so a
// single marker block captures the lot:
//   (a) unary left  fold over `+`  ( (((1+2)+3)+4) = 10 )
//   (b) unary right fold over `+`  same value, different associativity
//   (c) binary  fold over `,`     side-effect chain that ANDs each pack
//       element into a running accumulator.
//
//   $025000 = 0x000A   left-fold result
//   $025002 = 0x000A   right-fold result
//   $025004 = 0x0003   binary-comma fold: 0xFF & 0x07 & 0x0F & 0x03 = 0x03
//   $025006 = 0x0099   success marker
#include <stdint.h>


template <typename... Ts>
static int sumLeft(Ts... vs) {
    return (... + vs);
}


template <typename... Ts>
static int sumRight(Ts... vs) {
    return (vs + ...);
}


template <typename... Ts>
static int andAll(Ts... vs) {
    int acc = 0xFF;
    ((acc &= vs), ...);
    return acc;
}


int main(void) {
    int l = sumLeft(1, 2, 3, 4);
    int r = sumRight(1, 2, 3, 4);
    int a = andAll(0x07, 0x0F, 0x03);
    *(volatile uint16_t *)0x025000UL = (uint16_t)l;
    *(volatile uint16_t *)0x025002UL = (uint16_t)r;
    *(volatile uint16_t *)0x025004UL = (uint16_t)a;
    *(volatile uint16_t *)0x025006UL = 0x0099;
    return 0;
}
