| | #include <metal.hpp> |
| |
|
| | #include <cassert> |
| | #include <tuple> |
| |
|
| | #include "example.hpp" |
| |
|
| | #if 0 |
| | |
| | constexpr auto operator [](std::size_t i) |
| | -> std::tuple_element_t<i, std::tuple<T...>>& { |
| | return std::get<i>(*this); |
| | } |
| | |
| |
|
| | |
| | constexpr auto operator ""_c(long long i) |
| | -> metal::number<i> { |
| | return {}; |
| | } |
| | |
| | #endif |
| |
|
| | |
| | template<char... cs> |
| | constexpr auto operator ""_raw() |
| | -> metal::numbers<cs...> { |
| | return {}; |
| | } |
| | |
| |
|
| | |
| | IS_SAME(decltype(371_raw), metal::numbers<'3', '7', '1'>); |
| | IS_SAME(decltype(0x371_raw), metal::numbers<'0', 'x', '3', '7', '1'>); |
| | |
| |
|
| | #if !defined(METAL_WORKAROUND) |
| |
|
| | |
| | IS_SAME(decltype(3'7'1_raw), metal::numbers<'3', '\'', '7', '\'', '1'>); |
| | |
| |
|
| | HIDE( |
| | |
| | using tokens = metal::numbers<'3', '\'', '7', '\'', '1'>; |
| |
|
| | IS_SAME(metal::remove<tokens, metal::number<'\''>>, metal::numbers<'3', '7', '1'>); |
| | |
| | ) |
| | #endif |
| |
|
| | |
| | template<class token> |
| | using parse_digit = metal::at_key< |
| | metal::map< |
| | metal::pair<metal::number<'0'>, metal::number<0>>, |
| | metal::pair<metal::number<'1'>, metal::number<1>>, |
| | metal::pair<metal::number<'2'>, metal::number<2>>, |
| | metal::pair<metal::number<'3'>, metal::number<3>>, |
| | metal::pair<metal::number<'4'>, metal::number<4>>, |
| | metal::pair<metal::number<'5'>, metal::number<5>>, |
| | metal::pair<metal::number<'6'>, metal::number<6>>, |
| | metal::pair<metal::number<'7'>, metal::number<7>>, |
| | metal::pair<metal::number<'8'>, metal::number<8>>, |
| | metal::pair<metal::number<'9'>, metal::number<9>>, |
| | metal::pair<metal::number<'a'>, metal::number<10>>, |
| | metal::pair<metal::number<'b'>, metal::number<11>>, |
| | metal::pair<metal::number<'c'>, metal::number<12>>, |
| | metal::pair<metal::number<'d'>, metal::number<13>>, |
| | metal::pair<metal::number<'e'>, metal::number<14>>, |
| | metal::pair<metal::number<'f'>, metal::number<15>>, |
| | metal::pair<metal::number<'A'>, metal::number<10>>, |
| | metal::pair<metal::number<'B'>, metal::number<11>>, |
| | metal::pair<metal::number<'C'>, metal::number<12>>, |
| | metal::pair<metal::number<'D'>, metal::number<13>>, |
| | metal::pair<metal::number<'E'>, metal::number<14>>, |
| | metal::pair<metal::number<'F'>, metal::number<15>> |
| | >, |
| | token |
| | >; |
| | |
| |
|
| | HIDE( |
| | |
| | IS_SAME(metal::transform<metal::lambda<parse_digit>, metal::numbers<'3', '7', '1'>>, metal::numbers<3, 7, 1>); |
| | |
| | ) |
| |
|
| | HIDE( |
| | |
| | using radix = metal::number<10>; |
| | using digits = metal::numbers<3, 7, 1>; |
| |
|
| | template<class x, class y> |
| | using expr = metal::add<metal::mul<radix, x>, y>; |
| |
|
| | using lbd = metal::lambda<expr>; |
| |
|
| | IS_SAME(metal::accumulate<lbd, metal::number<0>, digits>, metal::number<371>); |
| | |
| | ) |
| |
|
| | HIDE( |
| | |
| | using radix = metal::number<10>; |
| | using digits = metal::numbers<3, 7, 1>; |
| |
|
| | using lbd = metal::bind< |
| | metal::lambda<metal::add>, |
| | metal::bind<metal::lambda<metal::mul>, metal::always<radix>, metal::_1>, |
| | metal::_2 |
| | >; |
| |
|
| | IS_SAME(metal::accumulate<lbd, metal::number<0>, digits>, metal::number<371>); |
| | |
| | ) |
| |
|
| | |
| | template<class radix, class digits> |
| | using assemble_number = metal::accumulate< |
| | metal::bind< |
| | metal::lambda<metal::add>, |
| | metal::bind<metal::lambda<metal::mul>, metal::always<radix>, metal::_1>, |
| | metal::_2 |
| | >, |
| | metal::number<0>, |
| | digits |
| | >; |
| | |
| |
|
| | |
| | template<class tokens> |
| | using parse_digits = metal::transform< |
| | metal::lambda<parse_digit>, |
| | metal::remove<tokens, metal::number<'\''>> |
| | >; |
| | |
| |
|
| | |
| | template<class tokens> |
| | struct parse_number {}; |
| |
|
| | template<class... tokens> |
| | struct parse_number<metal::list<tokens...>> { |
| | using type = assemble_number<metal::number<10>, parse_digits<metal::list<tokens...>>>; |
| | }; |
| |
|
| | template<class... tokens> |
| | struct parse_number<metal::list<metal::number<'0'>, tokens...>> { |
| | using type = assemble_number<metal::number<8>, parse_digits<metal::list<tokens...>>>; |
| | }; |
| |
|
| | template<class... tokens> |
| | struct parse_number<metal::list<metal::number<'0'>, metal::number<'x'>, tokens...>> { |
| | using type = assemble_number<metal::number<16>, parse_digits<metal::list<tokens...>>>; |
| | }; |
| |
|
| | template<class... tokens> |
| | struct parse_number<metal::list<metal::number<'0'>, metal::number<'X'>, tokens...>> { |
| | using type = assemble_number<metal::number<16>, parse_digits<metal::list<tokens...>>>; |
| | }; |
| |
|
| | template<class... tokens> |
| | struct parse_number<metal::list<metal::number<'0'>, metal::number<'b'>, tokens...>> { |
| | using type = assemble_number<metal::number<2>, parse_digits<metal::list<tokens...>>>; |
| | }; |
| |
|
| | template<class... tokens> |
| | struct parse_number<metal::list<metal::number<'0'>, metal::number<'B'>, tokens...>> { |
| | using type = assemble_number<metal::number<2>, parse_digits<metal::list<tokens...>>>; |
| | }; |
| | |
| |
|
| | |
| | template<char... cs> |
| | constexpr auto operator ""_c() |
| | -> metal::eval<parse_number<metal::numbers<cs...>>> { |
| | return {}; |
| | } |
| | |
| |
|
| | |
| | IS_SAME(decltype(01234567_c), metal::number<342391>); |
| | IS_SAME(decltype(123456789_c), metal::number<123456789>); |
| | IS_SAME(decltype(0xABCDEF_c), metal::number<11259375>); |
| | |
| |
|
| | IS_SAME(decltype(0Xabcdef_c), metal::number<11259375>); |
| |
|
| | #if !defined(METAL_WORKAROUND) |
| |
|
| | |
| | IS_SAME( |
| | decltype(0b111101101011011101011010101100101011110001000111000111000111000_c), |
| | metal::number<8888888888888888888> |
| | ); |
| | |
| |
|
| | IS_SAME( |
| | decltype(0B111101101011011101011010101100101011110001000111000111000111000_c), |
| | metal::number<8888888888888888888> |
| | ); |
| |
|
| | |
| | IS_SAME(decltype(1'2'3'4'5'6'7'8'9_c), metal::number<123456789>); |
| | |
| |
|
| | #endif |
| |
|
| | #if defined(METAL_WORKAROUND) |
| | template<class... T> |
| | struct AugmentedTuple : |
| | std::tuple<T...> |
| | { |
| | template<class... U> |
| | constexpr AugmentedTuple(U&&... args) : |
| | std::tuple<T...>(std::forward<U>(args)...) |
| | {} |
| |
|
| | template<metal::int_ i> |
| | constexpr auto operator [](metal::number<i>) const |
| | -> metal::at<metal::list<T...>, metal::number<i>> { |
| | return std::get<i>(*this); |
| | } |
| | }; |
| | #else |
| | |
| | template<class... T> |
| | struct AugmentedTuple : |
| | std::tuple<T...> |
| | { |
| | using std::tuple<T...>::tuple; |
| |
|
| | template<metal::int_ i> |
| | constexpr auto operator [](metal::number<i>) |
| | -> metal::at<metal::list<T...>, metal::number<i>>& { |
| | return std::get<i>(*this); |
| | } |
| | }; |
| | |
| | #endif |
| |
|
| | |
| | static_assert(std::get<1>(std::tuple<int, char, double>{42, 'a', 2.5}) == 'a', ""); |
| | |
| |
|
| | #if 0 |
| | |
| | static_assert(AugmentedTuple<int, char, double>{42, 'a', 2.5}[1] == 'a', ""); |
| | |
| | #endif |
| |
|
| | |
| | static_assert(AugmentedTuple<int, char, double>{42, 'a', 2.5}[metal::number<1>{}] == 'a', ""); |
| | |
| |
|
| | |
| | static_assert(AugmentedTuple<int, char, double>{42, 'a', 2.5}[1_c] == 'a', ""); |
| | |
| |
|