#include #include #include #include "example.hpp" #if 0 ///[naive_1] constexpr auto operator [](std::size_t i) -> std::tuple_element_t>& { return std::get(*this); } ///[naive_1] ///[naive_2] constexpr auto operator ""_c(long long i) -> metal::number { return {}; } ///[naive_2] #endif ///[_raw] template constexpr auto operator ""/**/_raw() -> metal::numbers { return {}; } ///[_raw] ///[_raw_ex1] IS_SAME(decltype(371_raw), metal::numbers<'3', '7', '1'>); IS_SAME(decltype(0x371_raw), metal::numbers<'0', 'x', '3', '7', '1'>); ///[_raw_ex1] #if !defined(METAL_WORKAROUND) ///[_raw_ex2] IS_SAME(decltype(3'7'1_raw), metal::numbers<'3', '\'', '7', '\'', '1'>); ///[_raw_ex2] HIDE( ///[remove] using tokens = metal::numbers<'3', '\'', '7', '\'', '1'>; IS_SAME(metal::remove>, metal::numbers<'3', '7', '1'>); ///[remove] ) #endif ///[parse_digit] template using parse_digit = metal::at_key< metal::map< metal::pair, metal::number<0>>, metal::pair, metal::number<1>>, metal::pair, metal::number<2>>, metal::pair, metal::number<3>>, metal::pair, metal::number<4>>, metal::pair, metal::number<5>>, metal::pair, metal::number<6>>, metal::pair, metal::number<7>>, metal::pair, metal::number<8>>, metal::pair, metal::number<9>>, metal::pair, metal::number<10>>, metal::pair, metal::number<11>>, metal::pair, metal::number<12>>, metal::pair, metal::number<13>>, metal::pair, metal::number<14>>, metal::pair, metal::number<15>>, metal::pair, metal::number<10>>, metal::pair, metal::number<11>>, metal::pair, metal::number<12>>, metal::pair, metal::number<13>>, metal::pair, metal::number<14>>, metal::pair, metal::number<15>> >, token >; ///[parse_digit] HIDE( ///[transform] IS_SAME(metal::transform, metal::numbers<'3', '7', '1'>>, metal::numbers<3, 7, 1>); ///[transform] ) HIDE( ///[accumulate_1] using radix = metal::number<10>; using digits = metal::numbers<3, 7, 1>; template using expr = metal::add, y>; using lbd = metal::lambda; IS_SAME(metal::accumulate, digits>, metal::number<371>); ///[accumulate_1] ) HIDE( ///[accumulate_2] using radix = metal::number<10>; using digits = metal::numbers<3, 7, 1>; using lbd = metal::bind< metal::lambda, metal::bind, metal::always, metal::_1>, metal::_2 >; IS_SAME(metal::accumulate, digits>, metal::number<371>); ///[accumulate_2] ) ///[assemble_number] template using assemble_number = metal::accumulate< metal::bind< metal::lambda, metal::bind, metal::always, metal::_1>, metal::_2 >, metal::number<0>, digits >; ///[assemble_number] ///[parse_digits] template using parse_digits = metal::transform< metal::lambda, metal::remove> >; ///[parse_digits] ///[parse_number] template struct parse_number {}; template struct parse_number> { using type = assemble_number, parse_digits>>; }; template struct parse_number, tokens...>> { using type = assemble_number, parse_digits>>; }; template struct parse_number, metal::number<'x'>, tokens...>> { using type = assemble_number, parse_digits>>; }; template struct parse_number, metal::number<'X'>, tokens...>> { using type = assemble_number, parse_digits>>; }; template struct parse_number, metal::number<'b'>, tokens...>> { using type = assemble_number, parse_digits>>; }; template struct parse_number, metal::number<'B'>, tokens...>> { using type = assemble_number, parse_digits>>; }; ///[parse_number] ///[_c] template constexpr auto operator ""/**/_c() -> metal::eval>> { return {}; } ///[_c] ///[_c_ex1] IS_SAME(decltype(01234567_c), metal::number<342391>); //octal IS_SAME(decltype(123456789_c), metal::number<123456789>); //decimal IS_SAME(decltype(0xABCDEF_c), metal::number<11259375>); //hexadecimal ///[_c_ex1] IS_SAME(decltype(0Xabcdef_c), metal::number<11259375>); #if !defined(METAL_WORKAROUND) ///[_c_ex2] IS_SAME( decltype(0b111101101011011101011010101100101011110001000111000111000111000_c), metal::number<8888888888888888888> ); ///[_c_ex2] IS_SAME( decltype(0B111101101011011101011010101100101011110001000111000111000111000_c), metal::number<8888888888888888888> ); ///[_c_ex3] IS_SAME(decltype(1'2'3'4'5'6'7'8'9_c), metal::number<123456789>); ///[_c_ex3] #endif #if defined(METAL_WORKAROUND) template struct AugmentedTuple : std::tuple { template constexpr AugmentedTuple(U&&... args) : std::tuple(std::forward(args)...) {} template constexpr auto operator [](metal::number) const -> metal::at, metal::number> { return std::get(*this); } }; #else ///[augmented_tuple] template struct AugmentedTuple : std::tuple { using std::tuple::tuple; template constexpr auto operator [](metal::number) -> metal::at, metal::number>& { return std::get(*this); } }; ///[augmented_tuple] #endif ///[teaser_1] static_assert(std::get<1>(std::tuple{42, 'a', 2.5}) == 'a', ""); ///[teaser_1] #if 0 ///[teaser_2] static_assert(AugmentedTuple{42, 'a', 2.5}[1] == 'a', ""); ///[teaser_2] #endif ///[teaser_3] static_assert(AugmentedTuple{42, 'a', 2.5}[metal::number<1>{}] == 'a', ""); ///[teaser_3] ///[teaser_4] static_assert(AugmentedTuple{42, 'a', 2.5}[1_c] == 'a', ""); ///[teaser_4]