//============================================================================// // // // artichoke programming language // // // // Copyright (C) 2025 Erick Saul Guzman Ramos, whoami.artichoke.dev // // // // // // This program is free software: you can redistribute it and/or modify // // it under the terms of the GNU Affero General Public License as published // // by the Free Software Foundation, either version 3 of the License, or // // (at your option) any later version. // // // // This program is distributed in the hope that it will be useful, // // but WITHOUT ANY WARRANTY; without even the implied warranty of // // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // // GNU Affero General Public License for more details. // // // // You should have received a copy of the GNU Affero General Public License // // along with this program. If not, see . // // // //============================================================================// #pragma once #include #include #include template requires( std::is_convertible_v, std::string_view> and std::is_same_v, std::ranges::range_value_t> ) arti::lang::Generator> InterleaveRanges(R1 &&r1, R2 &&r2) { auto it1 = std::ranges::begin(r1); auto end1 = std::ranges::end(r1); auto it2 = std::ranges::begin(r2); auto end2 = std::ranges::end(r2); while (it1 != end1 && it2 != end2) { yield *it1; ++it1; yield *it2; ++it2; } } static arti::lang::Generator WhitespaceGenerator(uint32_t maxLen = 5) { constexpr std::array spaceChars{ ' ', '\t', '\n' }; std::string str; std::random_device device; std::mt19937 engine(device()); std::uniform_int_distribution dist(1, maxLen); std::uniform_int_distribution distChars(0, 2); str.reserve(maxLen); while (true) { str.resize(0); auto sz = dist(engine); for (uint32_t i = 0; i < sz; ++i) { str += spaceChars[distChars(engine)]; } yield str; } } template requires(std::is_same_v, std::string_view>) static std::string SourceFromTokens(R &&tokens) { return InterleaveRanges(tokens, WhitespaceGenerator(10)) | std::views::join | std::ranges::to(); }