#pragma once
#include<iterator>
#include<ranges>
#include<concepts>
#include<algorithm>#include"internal/dev_env.hpp"
#include"internal/types.hpp"namespaceuni{template<classSize=internal::size_t>structnext_combination{usingsize_type=Size;private:size_type_size;public:next_combination(constsize_typesize):_size(size){};autosize()noexcept(NO_EXCEPT){returnthis->_size;}template<std::ranges::bidirectional_rangeR>autooperator()(R&&range)constnoexcept(NO_EXCEPT){returnthis->operator()(ALL(range));}template<std::bidirectional_iteratorI,std::sentinel_for<I>S>autooperator()(Ifirst,Slast)constnoexcept(NO_EXCEPT){autosubset=std::ranges::next(first,this->size());if(first==last||first==subset||last==subset)returnfalse;autosrc=subset;while(first!=src){--src;if(*src<*std::ranges::prev(last)){autodest=subset;while(*src>=*dest)++dest;std::ranges::iter_swap(src,dest);std::ranges::rotate(std::ranges::next(src),std::ranges::next(dest),last);std::ranges::rotate(subset,std::ranges::next(subset,std::ranges::distance(dest,last)-1),last);returntrue;}}std::ranges::rotate(first,subset,last);returnfalse;}};}// namespace uni