meta.hpp 127 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695269626972698269927002701270227032704270527062707270827092710271127122713271427152716271727182719272027212722272327242725272627272728272927302731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800280128022803280428052806280728082809281028112812281328142815281628172818281928202821282228232824282528262827282828292830283128322833283428352836283728382839284028412842284328442845284628472848284928502851285228532854285528562857285828592860286128622863286428652866286728682869287028712872287328742875287628772878287928802881288228832884288528862887288828892890289128922893289428952896289728982899290029012902290329042905290629072908290929102911291229132914291529162917291829192920292129222923292429252926292729282929293029312932293329342935293629372938293929402941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010301130123013301430153016301730183019302030213022302330243025302630273028302930303031303230333034303530363037303830393040304130423043304430453046304730483049305030513052305330543055305630573058305930603061306230633064306530663067306830693070307130723073307430753076307730783079308030813082308330843085308630873088308930903091309230933094309530963097309830993100310131023103310431053106310731083109311031113112311331143115311631173118311931203121312231233124312531263127312831293130313131323133313431353136313731383139314031413142314331443145314631473148314931503151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220322132223223322432253226322732283229323032313232323332343235323632373238323932403241324232433244324532463247324832493250325132523253325432553256325732583259326032613262326332643265326632673268326932703271327232733274327532763277327832793280328132823283328432853286328732883289329032913292329332943295329632973298329933003301330233033304330533063307330833093310331133123313331433153316331733183319332033213322332333243325332633273328332933303331333233333334333533363337333833393340334133423343334433453346334733483349335033513352335333543355335633573358335933603361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430343134323433343434353436343734383439344034413442344334443445344634473448344934503451345234533454345534563457345834593460346134623463346434653466346734683469347034713472347334743475347634773478347934803481348234833484348534863487348834893490349134923493349434953496349734983499350035013502350335043505350635073508350935103511351235133514351535163517351835193520352135223523352435253526352735283529353035313532353335343535353635373538353935403541354235433544354535463547354835493550355135523553355435553556355735583559356035613562356335643565356635673568356935703571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640364136423643364436453646364736483649365036513652365336543655365636573658365936603661366236633664366536663667366836693670367136723673367436753676367736783679368036813682368336843685368636873688368936903691369236933694369536963697369836993700370137023703370437053706370737083709371037113712371337143715371637173718371937203721372237233724372537263727372837293730373137323733373437353736373737383739374037413742374337443745374637473748374937503751375237533754375537563757375837593760376137623763376437653766376737683769377037713772377337743775377637773778377937803781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850385138523853385438553856385738583859386038613862386338643865386638673868386938703871387238733874387538763877387838793880388138823883388438853886388738883889389038913892389338943895389638973898389939003901390239033904390539063907390839093910391139123913391439153916391739183919392039213922392339243925392639273928392939303931393239333934393539363937393839393940394139423943394439453946394739483949395039513952395339543955395639573958395939603961396239633964396539663967396839693970397139723973
  1. /// \file meta.hpp Tiny meta-programming library.
  2. //
  3. // Meta library
  4. //
  5. // Copyright Eric Niebler 2014-present
  6. //
  7. // Use, modification and distribution is subject to the
  8. // Boost Software License, Version 1.0. (See accompanying
  9. // file LICENSE_1_0.txt or copy at
  10. // http://www.boost.org/LICENSE_1_0.txt)
  11. //
  12. // Project home: https://github.com/ericniebler/meta
  13. //
  14. #ifndef META_HPP
  15. #define META_HPP
  16. #include <cstddef>
  17. #include <initializer_list>
  18. #include <meta/meta_fwd.hpp>
  19. #include <type_traits>
  20. #include <utility>
  21. #ifdef __clang__
  22. #pragma GCC diagnostic push
  23. #pragma GCC diagnostic ignored "-Wunknown-pragmas"
  24. #pragma GCC diagnostic ignored "-Wpragmas"
  25. #pragma GCC diagnostic ignored "-Wdocumentation-deprecated-sync"
  26. #pragma GCC diagnostic ignored "-Wmissing-variable-declarations"
  27. #endif
  28. /// \defgroup meta Meta
  29. ///
  30. /// A tiny metaprogramming library
  31. /// \defgroup trait Trait
  32. /// Trait invocation/composition.
  33. /// \ingroup meta
  34. /// \defgroup invocation Invocation
  35. /// Trait invocation
  36. /// \ingroup trait
  37. /// \defgroup composition Composition
  38. /// Trait composition
  39. /// \ingroup trait
  40. /// \defgroup logical Logical
  41. /// Logical operations
  42. /// \ingroup meta
  43. /// \defgroup algorithm Algorithms
  44. /// Algorithms.
  45. /// \ingroup meta
  46. /// \defgroup query Query/Search
  47. /// Query and search algorithms
  48. /// \ingroup algorithm
  49. /// \defgroup transformation Transformation
  50. /// Transformation algorithms
  51. /// \ingroup algorithm
  52. /// \defgroup runtime Runtime
  53. /// Runtime algorithms
  54. /// \ingroup algorithm
  55. /// \defgroup datatype Datatype
  56. /// Datatypes.
  57. /// \ingroup meta
  58. /// \defgroup list list_like
  59. /// \ingroup datatype
  60. /// \defgroup integral Integer sequence
  61. /// Equivalent to C++14's `std::integer_sequence`
  62. /// \ingroup datatype
  63. /// \defgroup extension Extension
  64. /// Extend meta with your own datatypes.
  65. /// \ingroup datatype
  66. /// \defgroup math Math
  67. /// Integral constant arithmetic.
  68. /// \ingroup meta
  69. /// \defgroup lazy_trait lazy
  70. /// \ingroup trait
  71. /// \defgroup lazy_invocation lazy
  72. /// \ingroup invocation
  73. /// \defgroup lazy_composition lazy
  74. /// \ingroup composition
  75. /// \defgroup lazy_logical lazy
  76. /// \ingroup logical
  77. /// \defgroup lazy_query lazy
  78. /// \ingroup query
  79. /// \defgroup lazy_transformation lazy
  80. /// \ingroup transformation
  81. /// \defgroup lazy_list lazy
  82. /// \ingroup list
  83. /// \defgroup lazy_datatype lazy
  84. /// \ingroup datatype
  85. /// \defgroup lazy_math lazy
  86. /// \ingroup math
  87. /// Tiny metaprogramming library
  88. namespace meta
  89. {
  90. namespace detail
  91. {
  92. /// Returns a \p T nullptr
  93. template <typename T>
  94. constexpr T *_nullptr_v()
  95. {
  96. return nullptr;
  97. }
  98. #if META_CXX_VARIABLE_TEMPLATES
  99. template <typename T>
  100. META_INLINE_VAR constexpr T *nullptr_v = nullptr;
  101. #endif
  102. } // namespace detail
  103. /// An empty type.
  104. /// \ingroup datatype
  105. struct nil_
  106. {
  107. };
  108. /// Type alias for \p T::type.
  109. /// \ingroup invocation
  110. template <META_TYPE_CONSTRAINT(trait) T>
  111. using _t = typename T::type;
  112. #if META_CXX_VARIABLE_TEMPLATES || defined(META_DOXYGEN_INVOKED)
  113. /// Variable alias for \c T::type::value
  114. /// \note Requires C++14 or greater.
  115. /// \ingroup invocation
  116. template <META_TYPE_CONSTRAINT(integral) T>
  117. constexpr typename T::type::value_type _v = T::type::value;
  118. #endif
  119. /// Lazy versions of meta actions
  120. namespace lazy
  121. {
  122. /// \sa `meta::_t`
  123. /// \ingroup lazy_invocation
  124. template <typename T>
  125. using _t = defer<_t, T>;
  126. } // namespace lazy
  127. /// An integral constant wrapper for \c std::size_t.
  128. /// \ingroup integral
  129. template <std::size_t N>
  130. using size_t = std::integral_constant<std::size_t, N>;
  131. /// An integral constant wrapper for \c bool.
  132. /// \ingroup integral
  133. template <bool B>
  134. using bool_ = std::integral_constant<bool, B>;
  135. /// An integral constant wrapper for \c int.
  136. /// \ingroup integral
  137. template <int I>
  138. using int_ = std::integral_constant<int, I>;
  139. /// An integral constant wrapper for \c char.
  140. /// \ingroup integral
  141. template <char Ch>
  142. using char_ = std::integral_constant<char, Ch>;
  143. ///////////////////////////////////////////////////////////////////////////////////////////
  144. // Math operations
  145. /// An integral constant wrapper around the result of incrementing the wrapped integer \c
  146. /// T::type::value.
  147. template <META_TYPE_CONSTRAINT(integral) T>
  148. using inc = std::integral_constant<decltype(T::type::value + 1), T::type::value + 1>;
  149. /// An integral constant wrapper around the result of decrementing the wrapped integer \c
  150. /// T::type::value.
  151. template <META_TYPE_CONSTRAINT(integral) T>
  152. using dec = std::integral_constant<decltype(T::type::value - 1), T::type::value - 1>;
  153. /// An integral constant wrapper around the result of adding the two wrapped integers
  154. /// \c T::type::value and \c U::type::value.
  155. /// \ingroup math
  156. template <META_TYPE_CONSTRAINT(integral) T, META_TYPE_CONSTRAINT(integral) U>
  157. using plus = std::integral_constant<decltype(T::type::value + U::type::value),
  158. T::type::value + U::type::value>;
  159. /// An integral constant wrapper around the result of subtracting the two wrapped integers
  160. /// \c T::type::value and \c U::type::value.
  161. /// \ingroup math
  162. template <META_TYPE_CONSTRAINT(integral) T, META_TYPE_CONSTRAINT(integral) U>
  163. using minus = std::integral_constant<decltype(T::type::value - U::type::value),
  164. T::type::value - U::type::value>;
  165. /// An integral constant wrapper around the result of multiplying the two wrapped integers
  166. /// \c T::type::value and \c U::type::value.
  167. /// \ingroup math
  168. template <META_TYPE_CONSTRAINT(integral) T, META_TYPE_CONSTRAINT(integral) U>
  169. using multiplies = std::integral_constant<decltype(T::type::value * U::type::value),
  170. T::type::value * U::type::value>;
  171. /// An integral constant wrapper around the result of dividing the two wrapped integers \c
  172. /// T::type::value and \c U::type::value.
  173. /// \ingroup math
  174. template <META_TYPE_CONSTRAINT(integral) T, META_TYPE_CONSTRAINT(integral) U>
  175. using divides = std::integral_constant<decltype(T::type::value / U::type::value),
  176. T::type::value / U::type::value>;
  177. /// An integral constant wrapper around the result of negating the wrapped integer
  178. /// \c T::type::value.
  179. /// \ingroup math
  180. template <META_TYPE_CONSTRAINT(integral) T>
  181. using negate = std::integral_constant<decltype(-T::type::value), -T::type::value>;
  182. /// An integral constant wrapper around the remainder of dividing the two wrapped integers
  183. /// \c T::type::value and \c U::type::value.
  184. /// \ingroup math
  185. template <META_TYPE_CONSTRAINT(integral) T, META_TYPE_CONSTRAINT(integral) U>
  186. using modulus = std::integral_constant<decltype(T::type::value % U::type::value),
  187. T::type::value % U::type::value>;
  188. /// A Boolean integral constant wrapper around the result of comparing \c T::type::value and
  189. /// \c U::type::value for equality.
  190. /// \ingroup math
  191. template <META_TYPE_CONSTRAINT(integral) T, META_TYPE_CONSTRAINT(integral) U>
  192. using equal_to = bool_<T::type::value == U::type::value>;
  193. /// A Boolean integral constant wrapper around the result of comparing \c T::type::value and
  194. /// \c U::type::value for inequality.
  195. /// \ingroup math
  196. template <META_TYPE_CONSTRAINT(integral) T, META_TYPE_CONSTRAINT(integral) U>
  197. using not_equal_to = bool_<T::type::value != U::type::value>;
  198. /// A Boolean integral constant wrapper around \c true if \c T::type::value is greater than
  199. /// \c U::type::value; \c false, otherwise.
  200. /// \ingroup math
  201. template <META_TYPE_CONSTRAINT(integral) T, META_TYPE_CONSTRAINT(integral) U>
  202. using greater = bool_<(T::type::value > U::type::value)>;
  203. /// A Boolean integral constant wrapper around \c true if \c T::type::value is less than \c
  204. /// U::type::value; \c false, otherwise.
  205. /// \ingroup math
  206. template <META_TYPE_CONSTRAINT(integral) T, META_TYPE_CONSTRAINT(integral) U>
  207. using less = bool_<(T::type::value < U::type::value)>;
  208. /// A Boolean integral constant wrapper around \c true if \c T::type::value is greater than
  209. /// or equal to \c U::type::value; \c false, otherwise.
  210. /// \ingroup math
  211. template <META_TYPE_CONSTRAINT(integral) T, META_TYPE_CONSTRAINT(integral) U>
  212. using greater_equal = bool_<(T::type::value >= U::type::value)>;
  213. /// A Boolean integral constant wrapper around \c true if \c T::type::value is less than or
  214. /// equal to \c U::type::value; \c false, otherwise.
  215. /// \ingroup math
  216. template <META_TYPE_CONSTRAINT(integral) T, META_TYPE_CONSTRAINT(integral) U>
  217. using less_equal = bool_<(T::type::value <= U::type::value)>;
  218. /// An integral constant wrapper around the result of bitwise-and'ing the two wrapped
  219. /// integers \c T::type::value and \c U::type::value.
  220. /// \ingroup math
  221. template <META_TYPE_CONSTRAINT(integral) T, META_TYPE_CONSTRAINT(integral) U>
  222. using bit_and = std::integral_constant<decltype(T::type::value & U::type::value),
  223. T::type::value & U::type::value>;
  224. /// An integral constant wrapper around the result of bitwise-or'ing the two wrapped
  225. /// integers \c T::type::value and \c U::type::value.
  226. /// \ingroup math
  227. template <META_TYPE_CONSTRAINT(integral) T, META_TYPE_CONSTRAINT(integral) U>
  228. using bit_or = std::integral_constant<decltype(T::type::value | U::type::value),
  229. T::type::value | U::type::value>;
  230. /// An integral constant wrapper around the result of bitwise-exclusive-or'ing the two
  231. /// wrapped integers \c T::type::value and \c U::type::value.
  232. /// \ingroup math
  233. template <META_TYPE_CONSTRAINT(integral) T, META_TYPE_CONSTRAINT(integral) U>
  234. using bit_xor = std::integral_constant<decltype(T::type::value ^ U::type::value),
  235. T::type::value ^ U::type::value>;
  236. /// An integral constant wrapper around the result of bitwise-complementing the wrapped
  237. /// integer \c T::type::value.
  238. /// \ingroup math
  239. template <META_TYPE_CONSTRAINT(integral) T>
  240. using bit_not = std::integral_constant<decltype(~T::type::value), ~T::type::value>;
  241. namespace lazy
  242. {
  243. /// \sa 'meta::int'
  244. /// \ingroup lazy_math
  245. template <typename T>
  246. using inc = defer<inc, T>;
  247. /// \sa 'meta::dec'
  248. /// \ingroup lazy_math
  249. template <typename T>
  250. using dec = defer<dec, T>;
  251. /// \sa 'meta::plus'
  252. /// \ingroup lazy_math
  253. template <typename T, typename U>
  254. using plus = defer<plus, T, U>;
  255. /// \sa 'meta::minus'
  256. /// \ingroup lazy_math
  257. template <typename T, typename U>
  258. using minus = defer<minus, T, U>;
  259. /// \sa 'meta::multiplies'
  260. /// \ingroup lazy_math
  261. template <typename T, typename U>
  262. using multiplies = defer<multiplies, T, U>;
  263. /// \sa 'meta::divides'
  264. /// \ingroup lazy_math
  265. template <typename T, typename U>
  266. using divides = defer<divides, T, U>;
  267. /// \sa 'meta::negate'
  268. /// \ingroup lazy_math
  269. template <typename T>
  270. using negate = defer<negate, T>;
  271. /// \sa 'meta::modulus'
  272. /// \ingroup lazy_math
  273. template <typename T, typename U>
  274. using modulus = defer<modulus, T, U>;
  275. /// \sa 'meta::equal_to'
  276. /// \ingroup lazy_math
  277. template <typename T, typename U>
  278. using equal_to = defer<equal_to, T, U>;
  279. /// \sa 'meta::not_equal_t'
  280. /// \ingroup lazy_math
  281. template <typename T, typename U>
  282. using not_equal_to = defer<not_equal_to, T, U>;
  283. /// \sa 'meta::greater'
  284. /// \ingroup lazy_math
  285. template <typename T, typename U>
  286. using greater = defer<greater, T, U>;
  287. /// \sa 'meta::less'
  288. /// \ingroup lazy_math
  289. template <typename T, typename U>
  290. using less = defer<less, T, U>;
  291. /// \sa 'meta::greater_equal'
  292. /// \ingroup lazy_math
  293. template <typename T, typename U>
  294. using greater_equal = defer<greater_equal, T, U>;
  295. /// \sa 'meta::less_equal'
  296. /// \ingroup lazy_math
  297. template <typename T, typename U>
  298. using less_equal = defer<less_equal, T, U>;
  299. /// \sa 'meta::bit_and'
  300. /// \ingroup lazy_math
  301. template <typename T, typename U>
  302. using bit_and = defer<bit_and, T, U>;
  303. /// \sa 'meta::bit_or'
  304. /// \ingroup lazy_math
  305. template <typename T, typename U>
  306. using bit_or = defer<bit_or, T, U>;
  307. /// \sa 'meta::bit_xor'
  308. /// \ingroup lazy_math
  309. template <typename T, typename U>
  310. using bit_xor = defer<bit_xor, T, U>;
  311. /// \sa 'meta::bit_not'
  312. /// \ingroup lazy_math
  313. template <typename T>
  314. using bit_not = defer<bit_not, T>;
  315. } // namespace lazy
  316. /// \cond
  317. namespace detail
  318. {
  319. enum class indices_strategy_
  320. {
  321. done,
  322. repeat,
  323. recurse
  324. };
  325. constexpr indices_strategy_ strategy_(std::size_t cur, std::size_t end)
  326. {
  327. return cur >= end ? indices_strategy_::done
  328. : cur * 2 <= end ? indices_strategy_::repeat
  329. : indices_strategy_::recurse;
  330. }
  331. template <typename T>
  332. constexpr std::size_t range_distance_(T begin, T end)
  333. {
  334. return begin <= end ? static_cast<std::size_t>(end - begin)
  335. : throw "The start of the integer_sequence must not be "
  336. "greater than the end";
  337. }
  338. template <std::size_t End, typename State, indices_strategy_ Status_>
  339. struct make_indices_
  340. {
  341. using type = State;
  342. };
  343. template <typename T, T, typename>
  344. struct coerce_indices_
  345. {
  346. };
  347. } // namespace detail
  348. /// \endcond
  349. ///////////////////////////////////////////////////////////////////////////////////////////
  350. // integer_sequence
  351. #if !META_CXX_INTEGER_SEQUENCE
  352. /// A container for a sequence of compile-time integer constants.
  353. /// \ingroup integral
  354. template <typename T, T... Is>
  355. struct integer_sequence
  356. {
  357. using value_type = T;
  358. /// \return `sizeof...(Is)`
  359. static constexpr std::size_t size() noexcept { return sizeof...(Is); }
  360. };
  361. #endif
  362. ///////////////////////////////////////////////////////////////////////////////////////////
  363. // index_sequence
  364. /// A container for a sequence of compile-time integer constants of type
  365. /// \c std::size_t
  366. /// \ingroup integral
  367. template <std::size_t... Is>
  368. using index_sequence = integer_sequence<std::size_t, Is...>;
  369. #if META_HAS_MAKE_INTEGER_SEQ && !defined(META_DOXYGEN_INVOKED)
  370. // Implement make_integer_sequence and make_index_sequence with the
  371. // __make_integer_seq builtin on compilers that provide it. (Redirect
  372. // through decltype to workaround suspected clang bug.)
  373. /// \cond
  374. namespace detail
  375. {
  376. template <typename T, T N>
  377. __make_integer_seq<integer_sequence, T, N> make_integer_sequence_();
  378. }
  379. /// \endcond
  380. template <typename T, T N>
  381. using make_integer_sequence = decltype(detail::make_integer_sequence_<T, N>());
  382. template <std::size_t N>
  383. using make_index_sequence = make_integer_sequence<std::size_t, N>;
  384. #else
  385. /// Generate \c index_sequence containing integer constants [0,1,2,...,N-1].
  386. /// \par Complexity
  387. /// `O(log(N))`.
  388. /// \ingroup integral
  389. template <std::size_t N>
  390. using make_index_sequence =
  391. _t<detail::make_indices_<N, index_sequence<0>, detail::strategy_(1, N)>>;
  392. /// Generate \c integer_sequence containing integer constants [0,1,2,...,N-1].
  393. /// \par Complexity
  394. /// `O(log(N))`.
  395. /// \ingroup integral
  396. template <typename T, T N>
  397. using make_integer_sequence =
  398. _t<detail::coerce_indices_<T, 0, make_index_sequence<static_cast<std::size_t>(N)>>>;
  399. #endif
  400. ///////////////////////////////////////////////////////////////////////////////////////////
  401. // integer_range
  402. /// Makes the integer sequence `[From, To)`.
  403. /// \par Complexity
  404. /// `O(log(To - From))`.
  405. /// \ingroup integral
  406. template <typename T, T From, T To>
  407. using integer_range =
  408. _t<detail::coerce_indices_<T, From,
  409. make_index_sequence<detail::range_distance_(From, To)>>>;
  410. /// \cond
  411. namespace detail
  412. {
  413. template <typename, typename>
  414. struct concat_indices_
  415. {
  416. };
  417. template <std::size_t... Is, std::size_t... Js>
  418. struct concat_indices_<index_sequence<Is...>, index_sequence<Js...>>
  419. {
  420. using type = index_sequence<Is..., (Js + sizeof...(Is))...>;
  421. };
  422. template <>
  423. struct make_indices_<0u, index_sequence<0>, indices_strategy_::done>
  424. {
  425. using type = index_sequence<>;
  426. };
  427. template <std::size_t End, std::size_t... Values>
  428. struct make_indices_<End, index_sequence<Values...>, indices_strategy_::repeat>
  429. : make_indices_<End, index_sequence<Values..., (Values + sizeof...(Values))...>,
  430. detail::strategy_(sizeof...(Values) * 2, End)>
  431. {
  432. };
  433. template <std::size_t End, std::size_t... Values>
  434. struct make_indices_<End, index_sequence<Values...>, indices_strategy_::recurse>
  435. : concat_indices_<index_sequence<Values...>,
  436. make_index_sequence<End - sizeof...(Values)>>
  437. {
  438. };
  439. template <typename T, T Offset, std::size_t... Values>
  440. struct coerce_indices_<T, Offset, index_sequence<Values...>>
  441. {
  442. using type =
  443. integer_sequence<T, static_cast<T>(static_cast<T>(Values) + Offset)...>;
  444. };
  445. } // namespace detail
  446. /// \endcond
  447. /// Evaluate the invocable \p Fn with the arguments \p Args.
  448. /// \ingroup invocation
  449. template <META_TYPE_CONSTRAINT(invocable) Fn, typename... Args>
  450. using invoke = typename Fn::template invoke<Args...>;
  451. /// Lazy versions of meta actions
  452. namespace lazy
  453. {
  454. /// \sa `meta::invoke`
  455. /// \ingroup lazy_invocation
  456. template <typename Fn, typename... Args>
  457. using invoke = defer<invoke, Fn, Args...>;
  458. } // namespace lazy
  459. /// A trait that always returns its argument \p T. It is also an invocable
  460. /// that always returns \p T.
  461. /// \ingroup trait
  462. /// \ingroup invocation
  463. template <typename T>
  464. struct id
  465. {
  466. #if defined(META_WORKAROUND_CWG_1558) && !defined(META_DOXYGEN_INVOKED)
  467. // Redirect through decltype for compilers that have not
  468. // yet implemented CWG 1558:
  469. static id impl(void *);
  470. template <typename... Ts>
  471. using invoke = _t<decltype(id::impl(static_cast<list<Ts...> *>(nullptr)))>;
  472. #else
  473. template <typename...>
  474. using invoke = T;
  475. #endif
  476. using type = T;
  477. };
  478. /// An alias for type \p T. Useful in non-deduced contexts.
  479. /// \ingroup trait
  480. template <typename T>
  481. using id_t = _t<id<T>>;
  482. namespace lazy
  483. {
  484. /// \sa `meta::id`
  485. /// \ingroup lazy_trait
  486. /// \ingroup lazy_invocation
  487. template <typename T>
  488. using id = defer<id, T>;
  489. } // namespace lazy
  490. /// An alias for `void`.
  491. /// \ingroup trait
  492. #if defined(META_WORKAROUND_CWG_1558) && !defined(META_DOXYGEN_INVOKED)
  493. // Redirect through decltype for compilers that have not
  494. // yet implemented CWG 1558:
  495. template <typename... Ts>
  496. using void_ = invoke<id<void>, Ts...>;
  497. #else
  498. template <typename...>
  499. using void_ = void;
  500. #endif
  501. #if META_CXX_VARIABLE_TEMPLATES
  502. #ifdef META_CONCEPT
  503. /// `true` if `T::type` exists and names a type; `false` otherwise.
  504. /// \ingroup trait
  505. template <typename T>
  506. META_INLINE_VAR constexpr bool is_trait_v = trait<T>;
  507. /// `true` if `T::invoke` exists and names a class template; `false` otherwise.
  508. /// \ingroup trait
  509. template <typename T>
  510. META_INLINE_VAR constexpr bool is_callable_v = invocable<T>;
  511. #else // ^^^ Concepts / No concepts vvv
  512. /// \cond
  513. namespace detail
  514. {
  515. template <typename, typename = void>
  516. META_INLINE_VAR constexpr bool is_trait_ = false;
  517. template <typename T>
  518. META_INLINE_VAR constexpr bool is_trait_<T, void_<typename T::type>> = true;
  519. template <typename, typename = void>
  520. META_INLINE_VAR constexpr bool is_callable_ = false;
  521. template <typename T>
  522. META_INLINE_VAR constexpr bool is_callable_<T, void_<quote<T::template invoke>>> = true;
  523. } // namespace detail
  524. /// \endcond
  525. /// `true` if `T::type` exists and names a type; `false` otherwise.
  526. /// \ingroup trait
  527. template <typename T>
  528. META_INLINE_VAR constexpr bool is_trait_v = detail::is_trait_<T>;
  529. /// `true` if `T::invoke` exists and names a class template; `false` otherwise.
  530. /// \ingroup trait
  531. template <typename T>
  532. META_INLINE_VAR constexpr bool is_callable_v = detail::is_callable_<T>;
  533. #endif // Concepts vs. variable templates
  534. /// An alias for `std::true_type` if `T::type` exists and names a type; otherwise, it's an
  535. /// alias for `std::false_type`.
  536. /// \ingroup trait
  537. template <typename T>
  538. using is_trait = bool_<is_trait_v<T>>;
  539. /// An alias for `std::true_type` if `T::invoke` exists and names a class template;
  540. /// otherwise, it's an alias for `std::false_type`.
  541. /// \ingroup trait
  542. template <typename T>
  543. using is_callable = bool_<is_callable_v<T>>;
  544. #else // ^^^ META_CXX_VARIABLE_TEMPLATES / !META_CXX_VARIABLE_TEMPLATES vvv
  545. /// \cond
  546. namespace detail
  547. {
  548. template <typename, typename = void>
  549. struct is_trait_
  550. {
  551. using type = std::false_type;
  552. };
  553. template <typename T>
  554. struct is_trait_<T, void_<typename T::type>>
  555. {
  556. using type = std::true_type;
  557. };
  558. template <typename, typename = void>
  559. struct is_callable_
  560. {
  561. using type = std::false_type;
  562. };
  563. template <typename T>
  564. struct is_callable_<T, void_<quote<T::template invoke>>>
  565. {
  566. using type = std::true_type;
  567. };
  568. } // namespace detail
  569. /// \endcond
  570. template <typename T>
  571. using is_trait = _t<detail::is_trait_<T>>;
  572. /// An alias for `std::true_type` if `T::invoke` exists and names a class
  573. /// template or alias template; otherwise, it's an alias for
  574. /// `std::false_type`.
  575. /// \ingroup trait
  576. template <typename T>
  577. using is_callable = _t<detail::is_callable_<T>>;
  578. #endif
  579. /// \cond
  580. namespace detail
  581. {
  582. #ifdef META_CONCEPT
  583. template <template <typename...> class, typename...>
  584. struct defer_
  585. {
  586. };
  587. template <template <typename...> class C, typename... Ts>
  588. requires valid<C, Ts...> struct defer_<C, Ts...>
  589. {
  590. using type = C<Ts...>;
  591. };
  592. template <typename T, template <T...> class, T...>
  593. struct defer_i_
  594. {
  595. };
  596. template <typename T, template <T...> class C, T... Is>
  597. requires valid_i<T, C, Is...> struct defer_i_<T, C, Is...>
  598. {
  599. using type = C<Is...>;
  600. };
  601. #elif defined(META_WORKAROUND_MSVC_703656) // ^^^ Concepts / MSVC workaround vvv
  602. template <typename, template <typename...> class, typename...>
  603. struct _defer_
  604. {
  605. };
  606. template <template <typename...> class C, typename... Ts>
  607. struct _defer_<void_<C<Ts...>>, C, Ts...>
  608. {
  609. using type = C<Ts...>;
  610. };
  611. template <template <typename...> class C, typename... Ts>
  612. using defer_ = _defer_<void, C, Ts...>;
  613. template <typename, typename T, template <T...> class, T...>
  614. struct _defer_i_
  615. {
  616. };
  617. template <typename T, template <T...> class C, T... Is>
  618. struct _defer_i_<void_<C<Is...>>, T, C, Is...>
  619. {
  620. using type = C<Is...>;
  621. };
  622. template <typename T, template <T...> class C, T... Is>
  623. using defer_i_ = _defer_i_<void, T, C, Is...>;
  624. #else // ^^^ workaround ^^^ / vvv no workaround vvv
  625. template <template <typename...> class C, typename... Ts,
  626. template <typename...> class D = C>
  627. id<D<Ts...>> try_defer_(int);
  628. template <template <typename...> class C, typename... Ts>
  629. nil_ try_defer_(long);
  630. template <template <typename...> class C, typename... Ts>
  631. using defer_ = decltype(detail::try_defer_<C, Ts...>(0));
  632. template <typename T, template <T...> class C, T... Is, template <T...> class D = C>
  633. id<D<Is...>> try_defer_i_(int);
  634. template <typename T, template <T...> class C, T... Is>
  635. nil_ try_defer_i_(long);
  636. template <typename T, template <T...> class C, T... Is>
  637. using defer_i_ = decltype(detail::try_defer_i_<T, C, Is...>(0));
  638. #endif // Concepts vs. MSVC vs. Other
  639. template <typename T>
  640. using _t_t = _t<_t<T>>;
  641. } // namespace detail
  642. /// \endcond
  643. ///////////////////////////////////////////////////////////////////////////////////////////
  644. // defer
  645. /// A wrapper that defers the instantiation of a template \p C with type parameters \p Ts in
  646. /// a \c lambda or \c let expression.
  647. ///
  648. /// In the code below, the lambda would ideally be written as
  649. /// `lambda<_a,_b,push_back<_a,_b>>`, however this fails since `push_back` expects its first
  650. /// argument to be a list, not a placeholder. Instead, we express it using \c defer as
  651. /// follows:
  652. ///
  653. /// \code
  654. /// template <typename L>
  655. /// using reverse = reverse_fold<L, list<>, lambda<_a, _b, defer<push_back, _a, _b>>>;
  656. /// \endcode
  657. ///
  658. /// \ingroup invocation
  659. template <template <typename...> class C, typename... Ts>
  660. struct defer : detail::defer_<C, Ts...>
  661. {
  662. };
  663. ///////////////////////////////////////////////////////////////////////////////////////////
  664. // defer_i
  665. /// A wrapper that defers the instantiation of a template \p C with integral constant
  666. /// parameters \p Is in a \c lambda or \c let expression.
  667. /// \sa `defer`
  668. /// \ingroup invocation
  669. template <typename T, template <T...> class C, T... Is>
  670. struct defer_i : detail::defer_i_<T, C, Is...>
  671. {
  672. };
  673. ///////////////////////////////////////////////////////////////////////////////////////////
  674. // defer_trait
  675. /// A wrapper that defers the instantiation of a trait \p C with type parameters \p Ts in a
  676. /// \c lambda or \c let expression.
  677. /// \sa `defer`
  678. /// \ingroup invocation
  679. template <template <typename...> class C, typename... Ts>
  680. using defer_trait = defer<detail::_t_t, detail::defer_<C, Ts...>>;
  681. ///////////////////////////////////////////////////////////////////////////////////////////
  682. // defer_trait_i
  683. /// A wrapper that defers the instantiation of a trait \p C with integral constant
  684. /// parameters \p Is in a \c lambda or \c let expression.
  685. /// \sa `defer_i`
  686. /// \ingroup invocation
  687. template <typename T, template <T...> class C, T... Is>
  688. using defer_trait_i = defer<detail::_t_t, detail::defer_i_<T, C, Is...>>;
  689. /// An alias that computes the size of the type \p T.
  690. /// \par Complexity
  691. /// `O(1)`.
  692. /// \ingroup trait
  693. template <typename T>
  694. using sizeof_ = meta::size_t<sizeof(T)>;
  695. /// An alias that computes the alignment required for any instance of the type \p T.
  696. /// \par Complexity
  697. /// `O(1)`.
  698. /// \ingroup trait
  699. template <typename T>
  700. using alignof_ = meta::size_t<alignof(T)>;
  701. namespace lazy
  702. {
  703. /// \sa `meta::sizeof_`
  704. /// \ingroup lazy_trait
  705. template <typename T>
  706. using sizeof_ = defer<sizeof_, T>;
  707. /// \sa `meta::alignof_`
  708. /// \ingroup lazy_trait
  709. template <typename T>
  710. using alignof_ = defer<alignof_, T>;
  711. } // namespace lazy
  712. #if META_CXX_VARIABLE_TEMPLATES
  713. /// is
  714. /// Test whether a type \p T is an instantiation of class
  715. /// template \p C.
  716. /// \ingroup trait
  717. template <typename T, template <typename...> class C>
  718. using is = bool_<is_v<T, C>>;
  719. #else
  720. /// is
  721. /// \cond
  722. namespace detail
  723. {
  724. template <typename, template <typename...> class>
  725. struct is_ : std::false_type
  726. {
  727. };
  728. template <typename... Ts, template <typename...> class C>
  729. struct is_<C<Ts...>, C> : std::true_type
  730. {
  731. };
  732. } // namespace detail
  733. /// \endcond
  734. /// Test whether a type \c T is an instantiation of class
  735. /// template \c C.
  736. /// \ingroup trait
  737. template <typename T, template <typename...> class C>
  738. using is = _t<detail::is_<T, C>>;
  739. #endif
  740. /// Compose the Invocables \p Fns in the parameter pack \p Ts.
  741. /// \ingroup composition
  742. template <META_TYPE_CONSTRAINT(invocable)... Fns>
  743. struct compose_
  744. {
  745. };
  746. template <META_TYPE_CONSTRAINT(invocable) Fn0>
  747. struct compose_<Fn0>
  748. {
  749. template <typename... Ts>
  750. using invoke = invoke<Fn0, Ts...>;
  751. };
  752. template <META_TYPE_CONSTRAINT(invocable) Fn0, META_TYPE_CONSTRAINT(invocable)... Fns>
  753. struct compose_<Fn0, Fns...>
  754. {
  755. template <typename... Ts>
  756. using invoke = invoke<Fn0, invoke<compose_<Fns...>, Ts...>>;
  757. };
  758. template <typename... Fns>
  759. using compose = compose_<Fns...>;
  760. namespace lazy
  761. {
  762. /// \sa 'meta::compose'
  763. /// \ingroup lazy_composition
  764. template <typename... Fns>
  765. using compose = defer<compose, Fns...>;
  766. } // namespace lazy
  767. /// Turn a template \p C into an invocable.
  768. /// \ingroup composition
  769. template <template <typename...> class C>
  770. struct quote
  771. {
  772. // Indirection through defer here needed to avoid Core issue 1430
  773. // https://wg21.link/cwg1430
  774. template <typename... Ts>
  775. using invoke = _t<defer<C, Ts...>>;
  776. };
  777. /// Turn a template \p C taking literals of type \p T into a
  778. /// invocable.
  779. /// \ingroup composition
  780. template <typename T, template <T...> class C>
  781. struct quote_i
  782. {
  783. // Indirection through defer_i here needed to avoid Core issue 1430
  784. // https://wg21.link/cwg1430
  785. template <META_TYPE_CONSTRAINT(integral)... Ts>
  786. using invoke = _t<defer_i<T, C, Ts::type::value...>>;
  787. };
  788. #if defined(__GNUC__) && !defined(__clang__) && __GNUC__ == 4 && __GNUC_MINOR__ <= 8 && \
  789. !defined(META_DOXYGEN_INVOKED)
  790. template <template <typename...> class C>
  791. struct quote_trait
  792. {
  793. template <typename... Ts>
  794. using invoke = _t<invoke<quote<C>, Ts...>>;
  795. };
  796. template <typename T, template <T...> class C>
  797. struct quote_trait_i
  798. {
  799. template <typename... Ts>
  800. using invoke = _t<invoke<quote_i<T, C>, Ts...>>;
  801. };
  802. #else
  803. // clang-format off
  804. /// Turn a trait template \p C into an invocable.
  805. /// \code
  806. /// static_assert(std::is_same_v<invoke<quote_trait<std::add_const>, int>, int const>, "");
  807. /// \endcode
  808. /// \ingroup composition
  809. template <template <typename...> class C>
  810. using quote_trait = compose<quote<_t>, quote<C>>;
  811. /// Turn a trait template \p C taking literals of type \p T into an invocable.
  812. /// \ingroup composition
  813. template <typename T, template <T...> class C>
  814. using quote_trait_i = compose<quote<_t>, quote_i<T, C>>;
  815. // clang-format on
  816. #endif
  817. /// An invocable that partially applies the invocable
  818. /// \p Fn by binding the arguments \p Ts to the \e front of \p Fn.
  819. /// \ingroup composition
  820. template <META_TYPE_CONSTRAINT(invocable) Fn, typename... Ts>
  821. struct bind_front
  822. {
  823. template <typename... Us>
  824. using invoke = invoke<Fn, Ts..., Us...>;
  825. };
  826. /// An invocable that partially applies the invocable \p Fn by binding the
  827. /// arguments \p Us to the \e back of \p Fn.
  828. /// \ingroup composition
  829. template <META_TYPE_CONSTRAINT(invocable) Fn, typename... Us>
  830. struct bind_back
  831. {
  832. template <typename... Ts>
  833. using invoke = invoke<Fn, Ts..., Us...>;
  834. };
  835. namespace lazy
  836. {
  837. /// \sa 'meta::bind_front'
  838. /// \ingroup lazy_composition
  839. template <typename Fn, typename... Ts>
  840. using bind_front = defer<bind_front, Fn, Ts...>;
  841. /// \sa 'meta::bind_back'
  842. /// \ingroup lazy_composition
  843. template <typename Fn, typename... Ts>
  844. using bind_back = defer<bind_back, Fn, Ts...>;
  845. } // namespace lazy
  846. /// Extend meta with your own datatypes.
  847. namespace extension
  848. {
  849. /// A trait that unpacks the types in the type list \p L into the invocable
  850. /// \p Fn.
  851. /// \ingroup extension
  852. template <META_TYPE_CONSTRAINT(invocable) Fn, typename L>
  853. struct apply
  854. {
  855. };
  856. template <META_TYPE_CONSTRAINT(invocable) Fn, typename Ret, typename... Args>
  857. struct apply<Fn, Ret(Args...)> : lazy::invoke<Fn, Ret, Args...>
  858. {
  859. };
  860. template <META_TYPE_CONSTRAINT(invocable) Fn, template <typename...> class T,
  861. typename... Ts>
  862. struct apply<Fn, T<Ts...>> : lazy::invoke<Fn, Ts...>
  863. {
  864. };
  865. template <META_TYPE_CONSTRAINT(invocable) Fn, typename T, T... Is>
  866. struct apply<Fn, integer_sequence<T, Is...>>
  867. : lazy::invoke<Fn, std::integral_constant<T, Is>...>
  868. {
  869. };
  870. } // namespace extension
  871. /// Applies the invocable \p Fn using the types in the type list \p L as
  872. /// arguments.
  873. /// \ingroup invocation
  874. template <META_TYPE_CONSTRAINT(invocable) Fn, typename L>
  875. using apply = _t<extension::apply<Fn, L>>;
  876. namespace lazy
  877. {
  878. template <typename Fn, typename L>
  879. using apply = defer<apply, Fn, L>;
  880. }
  881. /// An invocable that takes a bunch of arguments, bundles them into a type
  882. /// list, and then calls the invocable \p Fn with the type list \p Q.
  883. /// \ingroup composition
  884. template <META_TYPE_CONSTRAINT(invocable) Fn,
  885. META_TYPE_CONSTRAINT(invocable) Q = quote<list>>
  886. using curry = compose<Fn, Q>;
  887. /// An invocable that takes a type list, unpacks the types, and then
  888. /// calls the invocable \p Fn with the types.
  889. /// \ingroup composition
  890. template <META_TYPE_CONSTRAINT(invocable) Fn>
  891. using uncurry = bind_front<quote<apply>, Fn>;
  892. namespace lazy
  893. {
  894. /// \sa 'meta::curry'
  895. /// \ingroup lazy_composition
  896. template <typename Fn, typename Q = quote<list>>
  897. using curry = defer<curry, Fn, Q>;
  898. /// \sa 'meta::uncurry'
  899. /// \ingroup lazy_composition
  900. template <typename Fn>
  901. using uncurry = defer<uncurry, Fn>;
  902. } // namespace lazy
  903. /// An invocable that reverses the order of the first two arguments.
  904. /// \ingroup composition
  905. template <META_TYPE_CONSTRAINT(invocable) Fn>
  906. struct flip
  907. {
  908. private:
  909. template <typename... Ts>
  910. struct impl
  911. {
  912. };
  913. template <typename A, typename B, typename... Ts>
  914. struct impl<A, B, Ts...> : lazy::invoke<Fn, B, A, Ts...>
  915. {
  916. };
  917. public:
  918. template <typename... Ts>
  919. using invoke = _t<impl<Ts...>>;
  920. };
  921. namespace lazy
  922. {
  923. /// \sa 'meta::flip'
  924. /// \ingroup lazy_composition
  925. template <typename Fn>
  926. using flip = defer<flip, Fn>;
  927. } // namespace lazy
  928. /// \cond
  929. namespace detail
  930. {
  931. template <typename...>
  932. struct on_
  933. {
  934. };
  935. template <typename Fn, typename... Gs>
  936. struct on_<Fn, Gs...>
  937. {
  938. template <typename... Ts>
  939. using invoke = invoke<Fn, invoke<compose<Gs...>, Ts>...>;
  940. };
  941. } // namespace detail
  942. /// \endcond
  943. /// Use as `on<Fn, Gs...>`. Creates an invocable that applies invocable \c Fn to the
  944. /// result of applying invocable `compose<Gs...>` to all the arguments.
  945. /// \ingroup composition
  946. template <META_TYPE_CONSTRAINT(invocable)... Fns>
  947. using on_ = detail::on_<Fns...>;
  948. template <typename... Fns>
  949. using on = on_<Fns...>;
  950. namespace lazy
  951. {
  952. /// \sa 'meta::on'
  953. /// \ingroup lazy_composition
  954. template <typename Fn, typename G>
  955. using on = defer<on, Fn, G>;
  956. } // namespace lazy
  957. ///////////////////////////////////////////////////////////////////////////////////////////
  958. // conditional_t
  959. /// \cond
  960. namespace detail
  961. {
  962. template <bool>
  963. struct _cond
  964. {
  965. template <typename Then, typename Else>
  966. using invoke = Then;
  967. };
  968. template <>
  969. struct _cond<false>
  970. {
  971. template <typename Then, typename Else>
  972. using invoke = Else;
  973. };
  974. } // namespace detail
  975. /// \endcond
  976. /// Select one type or another depending on a compile-time Boolean.
  977. /// \ingroup logical
  978. template <bool If, typename Then, typename Else = void>
  979. using conditional_t = typename detail::_cond<If>::template invoke<Then, Else>;
  980. ///////////////////////////////////////////////////////////////////////////////////////////
  981. // if_
  982. /// \cond
  983. namespace detail
  984. {
  985. #ifdef META_CONCEPT
  986. template <typename...>
  987. struct _if_
  988. {
  989. };
  990. template <typename If>
  991. requires integral<If>
  992. struct _if_<If> : std::enable_if<_v<If>>
  993. {
  994. };
  995. template <typename If, typename Then>
  996. requires integral<If>
  997. struct _if_<If, Then> : std::enable_if<_v<If>, Then>
  998. {
  999. };
  1000. template <typename If, typename Then, typename Else>
  1001. requires integral<If>
  1002. struct _if_<If, Then, Else> : std::conditional<_v<If>, Then, Else>
  1003. {
  1004. };
  1005. #elif defined(__clang__)
  1006. // Clang is faster with this implementation
  1007. template <typename, typename = bool>
  1008. struct _if_
  1009. {
  1010. };
  1011. template <typename If>
  1012. struct _if_<list<If>, decltype(bool(If::type::value))> : std::enable_if<If::type::value>
  1013. {
  1014. };
  1015. template <typename If, typename Then>
  1016. struct _if_<list<If, Then>, decltype(bool(If::type::value))>
  1017. : std::enable_if<If::type::value, Then>
  1018. {
  1019. };
  1020. template <typename If, typename Then, typename Else>
  1021. struct _if_<list<If, Then, Else>, decltype(bool(If::type::value))>
  1022. : std::conditional<If::type::value, Then, Else>
  1023. {
  1024. };
  1025. #else
  1026. // GCC seems to prefer this implementation
  1027. template <typename, typename = std::true_type>
  1028. struct _if_
  1029. {
  1030. };
  1031. template <typename If>
  1032. struct _if_<list<If>, bool_<If::type::value>>
  1033. {
  1034. using type = void;
  1035. };
  1036. template <typename If, typename Then>
  1037. struct _if_<list<If, Then>, bool_<If::type::value>>
  1038. {
  1039. using type = Then;
  1040. };
  1041. template <typename If, typename Then, typename Else>
  1042. struct _if_<list<If, Then, Else>, bool_<If::type::value>>
  1043. {
  1044. using type = Then;
  1045. };
  1046. template <typename If, typename Then, typename Else>
  1047. struct _if_<list<If, Then, Else>, bool_<!If::type::value>>
  1048. {
  1049. using type = Else;
  1050. };
  1051. #endif
  1052. } // namespace detail
  1053. /// \endcond
  1054. /// Select one type or another depending on a compile-time Boolean.
  1055. /// \ingroup logical
  1056. #ifdef META_CONCEPT
  1057. template <typename... Args>
  1058. using if_ = _t<detail::_if_<Args...>>;
  1059. /// Select one type or another depending on a compile-time Boolean.
  1060. /// \ingroup logical
  1061. template <bool If, typename... Args>
  1062. using if_c = _t<detail::_if_<bool_<If>, Args...>>;
  1063. #else
  1064. template <typename... Args>
  1065. using if_ = _t<detail::_if_<list<Args...>>>;
  1066. template <bool If, typename... Args>
  1067. using if_c = _t<detail::_if_<list<bool_<If>, Args...>>>;
  1068. #endif
  1069. namespace lazy
  1070. {
  1071. /// \sa 'meta::if_'
  1072. /// \ingroup lazy_logical
  1073. template <typename... Args>
  1074. using if_ = defer<if_, Args...>;
  1075. /// \sa 'meta::if_c'
  1076. /// \ingroup lazy_logical
  1077. template <bool If, typename... Args>
  1078. using if_c = if_<bool_<If>, Args...>;
  1079. } // namespace lazy
  1080. /// \cond
  1081. namespace detail
  1082. {
  1083. #ifdef META_CONCEPT
  1084. template <typename...>
  1085. struct _and_
  1086. {
  1087. };
  1088. template <>
  1089. struct _and_<> : std::true_type
  1090. {
  1091. };
  1092. template <typename B, typename... Bs>
  1093. requires integral<B> && (bool(B::type::value))
  1094. struct _and_<B, Bs...> : _and_<Bs...>
  1095. {
  1096. };
  1097. template <typename B, typename... Bs>
  1098. requires integral<B> && (!bool(B::type::value))
  1099. struct _and_<B, Bs...> : std::false_type
  1100. {
  1101. };
  1102. template <typename...>
  1103. struct _or_
  1104. {
  1105. };
  1106. template <>
  1107. struct _or_<> : std::false_type
  1108. {
  1109. };
  1110. template <typename B, typename... Bs>
  1111. requires integral<B> && (bool(B::type::value))
  1112. struct _or_<B, Bs...> : std::true_type
  1113. {
  1114. };
  1115. template <typename B, typename... Bs>
  1116. requires integral<B> && (!bool(B::type::value))
  1117. struct _or_<B, Bs...> : _or_<Bs...>
  1118. {
  1119. };
  1120. #else
  1121. template <bool>
  1122. struct _and_
  1123. {
  1124. template <typename...>
  1125. using invoke = std::true_type;
  1126. };
  1127. template <>
  1128. struct _and_<false>
  1129. {
  1130. template <typename B, typename... Bs>
  1131. using invoke = invoke<
  1132. if_c<!B::type::value, id<std::false_type>, _and_<0 == sizeof...(Bs)>>,
  1133. Bs...>;
  1134. };
  1135. template <bool>
  1136. struct _or_
  1137. {
  1138. template <typename = void>
  1139. using invoke = std::false_type;
  1140. };
  1141. template <>
  1142. struct _or_<false>
  1143. {
  1144. template <typename B, typename... Bs>
  1145. using invoke = invoke<
  1146. if_c<B::type::value, id<std::true_type>, _or_<0 == sizeof...(Bs)>>,
  1147. Bs...>;
  1148. };
  1149. #endif
  1150. } // namespace detail
  1151. /// \endcond
  1152. /// Logically negate the Boolean parameter
  1153. /// \ingroup logical
  1154. template <bool B>
  1155. using not_c = bool_<!B>;
  1156. /// Logically negate the integral constant-wrapped Boolean parameter.
  1157. /// \ingroup logical
  1158. template <META_TYPE_CONSTRAINT(integral) B>
  1159. using not_ = not_c<B::type::value>;
  1160. #if META_CXX_FOLD_EXPRESSIONS && !defined(META_WORKAROUND_GCC_UNKNOWN1)
  1161. template <bool... Bs>
  1162. META_INLINE_VAR constexpr bool and_v = (true && ... && Bs);
  1163. /// Logically AND together all the Boolean parameters
  1164. /// \ingroup logical
  1165. template <bool... Bs>
  1166. #if defined(META_WORKAROUND_MSVC_756112) || defined(META_WORKAROUND_GCC_86356)
  1167. using and_c = bool_<and_v<Bs...>>;
  1168. #else
  1169. using and_c = bool_<(true && ... && Bs)>;
  1170. #endif
  1171. #else
  1172. #if defined(META_WORKAROUND_GCC_66405)
  1173. template <bool... Bs>
  1174. using and_c = meta::bool_<
  1175. META_IS_SAME(integer_sequence<bool, true, Bs...>,
  1176. integer_sequence<bool, Bs..., true>)>;
  1177. #else
  1178. template <bool... Bs>
  1179. struct and_c
  1180. : meta::bool_<
  1181. META_IS_SAME(integer_sequence<bool, Bs...>,
  1182. integer_sequence<bool, (Bs || true)...>)>
  1183. {};
  1184. #endif
  1185. #if META_CXX_VARIABLE_TEMPLATES
  1186. template <bool... Bs>
  1187. META_INLINE_VAR constexpr bool and_v =
  1188. META_IS_SAME(integer_sequence<bool, Bs...>,
  1189. integer_sequence<bool, (Bs || true)...>);
  1190. #endif
  1191. #endif
  1192. /// Logically AND together all the integral constant-wrapped Boolean
  1193. /// parameters, \e without short-circuiting.
  1194. /// \ingroup logical
  1195. template <META_TYPE_CONSTRAINT(integral)... Bs>
  1196. using strict_and_ = and_c<Bs::type::value...>;
  1197. template <typename... Bs>
  1198. using strict_and = strict_and_<Bs...>;
  1199. /// Logically AND together all the integral constant-wrapped Boolean
  1200. /// parameters, \e with short-circuiting.
  1201. /// \ingroup logical
  1202. template <typename... Bs>
  1203. #ifdef META_CONCEPT
  1204. using and_ = _t<detail::_and_<Bs...>>;
  1205. #else
  1206. // Make a trip through defer<> to avoid CWG1430
  1207. // https://wg21.link/cwg1430
  1208. using and_ = _t<defer<detail::_and_<0 == sizeof...(Bs)>::template invoke, Bs...>>;
  1209. #endif
  1210. /// Logically OR together all the Boolean parameters
  1211. /// \ingroup logical
  1212. #if META_CXX_FOLD_EXPRESSIONS && !defined(META_WORKAROUND_GCC_UNKNOWN1)
  1213. template <bool... Bs>
  1214. META_INLINE_VAR constexpr bool or_v = (false || ... || Bs);
  1215. template <bool... Bs>
  1216. #if defined(META_WORKAROUND_MSVC_756112) || defined(META_WORKAROUND_GCC_86356)
  1217. using or_c = bool_<or_v<Bs...>>;
  1218. #else
  1219. using or_c = bool_<(false || ... || Bs)>;
  1220. #endif
  1221. #else
  1222. template <bool... Bs>
  1223. struct or_c
  1224. : meta::bool_<
  1225. !META_IS_SAME(integer_sequence<bool, Bs...>,
  1226. integer_sequence<bool, (Bs && false)...>)>
  1227. {};
  1228. #if META_CXX_VARIABLE_TEMPLATES
  1229. template <bool... Bs>
  1230. META_INLINE_VAR constexpr bool or_v =
  1231. !META_IS_SAME(integer_sequence<bool, Bs...>,
  1232. integer_sequence<bool, (Bs && false)...>);
  1233. #endif
  1234. #endif
  1235. /// Logically OR together all the integral constant-wrapped Boolean
  1236. /// parameters, \e without short-circuiting.
  1237. /// \ingroup logical
  1238. template <META_TYPE_CONSTRAINT(integral)... Bs>
  1239. using strict_or_ = or_c<Bs::type::value...>;
  1240. template <typename... Bs>
  1241. using strict_or = strict_or_<Bs...>;
  1242. /// Logically OR together all the integral constant-wrapped Boolean
  1243. /// parameters, \e with short-circuiting.
  1244. /// \ingroup logical
  1245. template <typename... Bs>
  1246. #ifdef META_CONCEPT
  1247. using or_ = _t<detail::_or_<Bs...>>;
  1248. #else
  1249. // Make a trip through defer<> to avoid CWG1430
  1250. // https://wg21.link/cwg1430
  1251. using or_ = _t<defer<detail::_or_<0 == sizeof...(Bs)>::template invoke, Bs...>>;
  1252. #endif
  1253. namespace lazy
  1254. {
  1255. /// \sa 'meta::and_'
  1256. /// \ingroup lazy_logical
  1257. template <typename... Bs>
  1258. using and_ = defer<and_, Bs...>;
  1259. /// \sa 'meta::or_'
  1260. /// \ingroup lazy_logical
  1261. template <typename... Bs>
  1262. using or_ = defer<or_, Bs...>;
  1263. /// \sa 'meta::not_'
  1264. /// \ingroup lazy_logical
  1265. template <typename B>
  1266. using not_ = defer<not_, B>;
  1267. /// \sa 'meta::strict_and'
  1268. /// \ingroup lazy_logical
  1269. template <typename... Bs>
  1270. using strict_and = defer<strict_and, Bs...>;
  1271. /// \sa 'meta::strict_or'
  1272. /// \ingroup lazy_logical
  1273. template <typename... Bs>
  1274. using strict_or = defer<strict_or, Bs...>;
  1275. } // namespace lazy
  1276. ///////////////////////////////////////////////////////////////////////////////////////////
  1277. // fold
  1278. /// \cond
  1279. namespace detail
  1280. {
  1281. template <typename, typename, typename>
  1282. struct fold_
  1283. {
  1284. };
  1285. template <typename Fn, typename T0, typename T1, typename T2, typename T3, typename T4,
  1286. typename T5, typename T6, typename T7, typename T8, typename T9>
  1287. struct compose10_
  1288. {
  1289. template <typename X, typename Y>
  1290. using F = invoke<Fn, X, Y>;
  1291. template <typename S>
  1292. using invoke =
  1293. F<F<F<F<F<F<F<F<F<F<_t<S>, T0>, T1>, T2>, T3>, T4>, T5>, T6>, T7>, T8>, T9>;
  1294. };
  1295. #ifdef META_CONCEPT
  1296. template <typename Fn>
  1297. struct compose_
  1298. {
  1299. template <typename X, typename Y>
  1300. using F = invoke<Fn, X, Y>;
  1301. template <typename T0, typename T1, typename T2, typename T3, typename T4,
  1302. typename T5, typename T6, typename T7, typename T8, typename T9,
  1303. typename State>
  1304. using invoke =
  1305. F<F<F<F<F<F<F<F<F<F<State, T0>, T1>, T2>, T3>, T4>, T5>, T6>, T7>, T8>, T9>;
  1306. };
  1307. template <typename State, typename Fn>
  1308. struct fold_<list<>, State, Fn>
  1309. {
  1310. using type = State;
  1311. };
  1312. template <typename Head, typename... Tail, typename State, typename Fn>
  1313. requires valid<invoke, Fn, State, Head>
  1314. struct fold_<list<Head, Tail...>, State, Fn>
  1315. : fold_<list<Tail...>, invoke<Fn, State, Head>, Fn>
  1316. {
  1317. };
  1318. template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5,
  1319. typename T6, typename T7, typename T8, typename T9, typename... Tail,
  1320. typename State, typename Fn>
  1321. requires valid<invoke, compose_<Fn>, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, State>
  1322. struct fold_<list<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, Tail...>, State, Fn>
  1323. : fold_<list<Tail...>,
  1324. invoke<compose_<Fn>, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, State>, Fn>
  1325. {
  1326. };
  1327. #else // ^^^ Concepts / no Concepts vvv
  1328. template <typename Fn, typename T0>
  1329. struct compose1_
  1330. {
  1331. template <typename X>
  1332. using invoke = invoke<Fn, _t<X>, T0>;
  1333. };
  1334. template <typename State, typename Fn>
  1335. struct fold_<list<>, State, Fn> : State
  1336. {
  1337. };
  1338. template <typename Head, typename... Tail, typename State, typename Fn>
  1339. struct fold_<list<Head, Tail...>, State, Fn>
  1340. : fold_<list<Tail...>, lazy::invoke<compose1_<Fn, Head>, State>, Fn>
  1341. {
  1342. };
  1343. template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5,
  1344. typename T6, typename T7, typename T8, typename T9, typename... Tail,
  1345. typename State, typename Fn>
  1346. struct fold_<list<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, Tail...>, State, Fn>
  1347. : fold_<list<Tail...>,
  1348. lazy::invoke<compose10_<Fn, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9>, State>, Fn>
  1349. {
  1350. };
  1351. #endif // META_CONCEPT
  1352. } // namespace detail
  1353. /// \endcond
  1354. /// Return a new \c meta::list constructed by doing a left fold of the list \p L using
  1355. /// binary invocable \p Fn and initial state \p State. That is, the \c State(N) for
  1356. /// the list element \c A(N) is computed by `Fn(State(N-1), A(N)) -> State(N)`.
  1357. /// \par Complexity
  1358. /// `O(N)`.
  1359. /// \ingroup transformation
  1360. template <META_TYPE_CONSTRAINT(list_like) L, typename State, META_TYPE_CONSTRAINT(invocable) Fn>
  1361. #ifdef META_CONCEPT
  1362. using fold = _t<detail::fold_<L, State, Fn>>;
  1363. #else
  1364. using fold = _t<detail::fold_<L, id<State>, Fn>>;
  1365. #endif
  1366. /// An alias for `meta::fold`.
  1367. /// \par Complexity
  1368. /// `O(N)`.
  1369. /// \ingroup transformation
  1370. template <META_TYPE_CONSTRAINT(list_like) L, typename State, META_TYPE_CONSTRAINT(invocable) Fn>
  1371. using accumulate = fold<L, State, Fn>;
  1372. namespace lazy
  1373. {
  1374. /// \sa 'meta::foldl'
  1375. /// \ingroup lazy_transformation
  1376. template <typename L, typename State, typename Fn>
  1377. using fold = defer<fold, L, State, Fn>;
  1378. /// \sa 'meta::accumulate'
  1379. /// \ingroup lazy_transformation
  1380. template <typename L, typename State, typename Fn>
  1381. using accumulate = defer<accumulate, L, State, Fn>;
  1382. } // namespace lazy
  1383. ///////////////////////////////////////////////////////////////////////////////////////////
  1384. // reverse_fold
  1385. /// \cond
  1386. namespace detail
  1387. {
  1388. template <typename, typename, typename>
  1389. struct reverse_fold_
  1390. {
  1391. };
  1392. template <typename State, typename Fn>
  1393. struct reverse_fold_<list<>, State, Fn>
  1394. {
  1395. using type = State;
  1396. };
  1397. #ifdef META_CONCEPT
  1398. template <typename Head, typename... L, typename State, typename Fn>
  1399. requires trait<reverse_fold_<list<L...>, State, Fn>> struct reverse_fold_<
  1400. list<Head, L...>, State, Fn>
  1401. : lazy::invoke<Fn, _t<reverse_fold_<list<L...>, State, Fn>>, Head>
  1402. {
  1403. };
  1404. #else
  1405. template <typename Head, typename... Tail, typename State, typename Fn>
  1406. struct reverse_fold_<list<Head, Tail...>, State, Fn>
  1407. : lazy::invoke<compose1_<Fn, Head>, reverse_fold_<list<Tail...>, State, Fn>>
  1408. {
  1409. };
  1410. #endif
  1411. template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5,
  1412. typename T6, typename T7, typename T8, typename T9, typename... Tail,
  1413. typename State, typename Fn>
  1414. struct reverse_fold_<list<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, Tail...>, State, Fn>
  1415. : lazy::invoke<compose10_<Fn, T9, T8, T7, T6, T5, T4, T3, T2, T1, T0>,
  1416. reverse_fold_<list<Tail...>, State, Fn>>
  1417. {
  1418. };
  1419. } // namespace detail
  1420. /// \endcond
  1421. /// Return a new \c meta::list constructed by doing a right fold of the list \p L using
  1422. /// binary invocable \p Fn and initial state \p State. That is, the \c State(N) for the list
  1423. /// element \c A(N) is computed by `Fn(A(N), State(N+1)) -> State(N)`.
  1424. /// \par Complexity
  1425. /// `O(N)`.
  1426. /// \ingroup transformation
  1427. template <META_TYPE_CONSTRAINT(list_like) L, typename State, META_TYPE_CONSTRAINT(invocable) Fn>
  1428. using reverse_fold = _t<detail::reverse_fold_<L, State, Fn>>;
  1429. namespace lazy
  1430. {
  1431. /// \sa 'meta::foldr'
  1432. /// \ingroup lazy_transformation
  1433. template <typename L, typename State, typename Fn>
  1434. using reverse_fold = defer<reverse_fold, L, State, Fn>;
  1435. } // namespace lazy
  1436. ///////////////////////////////////////////////////////////////////////////////////////////
  1437. // npos
  1438. /// A special value used to indicate no matches. It equals the maximum
  1439. /// value representable by std::size_t.
  1440. /// \ingroup list
  1441. using npos = meta::size_t<std::size_t(-1)>;
  1442. ///////////////////////////////////////////////////////////////////////////////////////////
  1443. // list
  1444. /// A list of types.
  1445. /// \ingroup list
  1446. template <typename... Ts>
  1447. struct list
  1448. {
  1449. using type = list;
  1450. /// \return `sizeof...(Ts)`
  1451. static constexpr std::size_t size() noexcept { return sizeof...(Ts); }
  1452. };
  1453. ///////////////////////////////////////////////////////////////////////////////////////////
  1454. // size
  1455. /// An integral constant wrapper that is the size of the \c meta::list
  1456. /// \p L.
  1457. /// \ingroup list
  1458. template <META_TYPE_CONSTRAINT(list_like) L>
  1459. using size = meta::size_t<L::size()>;
  1460. namespace lazy
  1461. {
  1462. /// \sa 'meta::size'
  1463. /// \ingroup lazy_list
  1464. template <typename L>
  1465. using size = defer<size, L>;
  1466. } // namespace lazy
  1467. ///////////////////////////////////////////////////////////////////////////////////////////
  1468. // concat
  1469. /// \cond
  1470. namespace detail
  1471. {
  1472. template <typename... Lists>
  1473. struct concat_
  1474. {
  1475. };
  1476. template <>
  1477. struct concat_<>
  1478. {
  1479. using type = list<>;
  1480. };
  1481. template <typename... L1>
  1482. struct concat_<list<L1...>>
  1483. {
  1484. using type = list<L1...>;
  1485. };
  1486. template <typename... L1, typename... L2>
  1487. struct concat_<list<L1...>, list<L2...>>
  1488. {
  1489. using type = list<L1..., L2...>;
  1490. };
  1491. template <typename... L1, typename... L2, typename... L3>
  1492. struct concat_<list<L1...>, list<L2...>, list<L3...>>
  1493. {
  1494. using type = list<L1..., L2..., L3...>;
  1495. };
  1496. template <typename... L1, typename... L2, typename... L3, typename... Rest>
  1497. struct concat_<list<L1...>, list<L2...>, list<L3...>, Rest...>
  1498. : concat_<list<L1..., L2..., L3...>, Rest...>
  1499. {
  1500. };
  1501. template <typename... L1, typename... L2, typename... L3, typename... L4,
  1502. typename... L5, typename... L6, typename... L7, typename... L8,
  1503. typename... L9, typename... L10, typename... Rest>
  1504. struct concat_<list<L1...>, list<L2...>, list<L3...>, list<L4...>, list<L5...>,
  1505. list<L6...>, list<L7...>, list<L8...>, list<L9...>, list<L10...>,
  1506. Rest...>
  1507. : concat_<list<L1..., L2..., L3..., L4..., L5..., L6..., L7..., L8..., L9..., L10...>,
  1508. Rest...>
  1509. {
  1510. };
  1511. } // namespace detail
  1512. /// \endcond
  1513. /// Concatenates several lists into a single list.
  1514. /// \pre The parameters must all be instantiations of \c meta::list.
  1515. /// \par Complexity
  1516. /// `O(L)` where `L` is the number of lists in the list of lists.
  1517. /// \ingroup transformation
  1518. template <META_TYPE_CONSTRAINT(list_like)... Ls>
  1519. using concat_ = _t<detail::concat_<Ls...>>;
  1520. template <typename... Lists>
  1521. using concat = concat_<Lists...>;
  1522. namespace lazy
  1523. {
  1524. /// \sa 'meta::concat'
  1525. /// \ingroup lazy_transformation
  1526. template <typename... Lists>
  1527. using concat = defer<concat, Lists...>;
  1528. } // namespace lazy
  1529. /// Joins a list of lists into a single list.
  1530. /// \pre The parameter must be an instantiation of \c meta::list\<T...\>
  1531. /// where each \c T is itself an instantiation of \c meta::list.
  1532. /// \par Complexity
  1533. /// `O(L)` where `L` is the number of lists in the list of
  1534. /// lists.
  1535. /// \ingroup transformation
  1536. template <META_TYPE_CONSTRAINT(list_like) ListOfLists>
  1537. using join = apply<quote<concat>, ListOfLists>;
  1538. namespace lazy
  1539. {
  1540. /// \sa 'meta::join'
  1541. /// \ingroup lazy_transformation
  1542. template <typename ListOfLists>
  1543. using join = defer<join, ListOfLists>;
  1544. } // namespace lazy
  1545. ///////////////////////////////////////////////////////////////////////////////////////////
  1546. // transform
  1547. /// \cond
  1548. namespace detail
  1549. {
  1550. #ifdef META_CONCEPT
  1551. template <typename... Args>
  1552. struct transform_
  1553. {
  1554. };
  1555. template <typename... Ts, typename Fn>
  1556. requires invocable<Fn> && and_v<valid<invoke, Fn, Ts>...>
  1557. struct transform_<list<Ts...>, Fn>
  1558. {
  1559. using type = list<invoke<Fn, Ts>...>;
  1560. };
  1561. template <typename... Ts, typename... Us, typename Fn>
  1562. requires invocable<Fn> && and_v<valid<invoke, Fn, Ts, Us>...>
  1563. struct transform_<list<Ts...>, list<Us...>, Fn>
  1564. {
  1565. using type = list<invoke<Fn, Ts, Us>...>;
  1566. };
  1567. #else
  1568. template <typename, typename = void>
  1569. struct transform_
  1570. {
  1571. };
  1572. template <typename... Ts, typename Fn>
  1573. struct transform_<list<list<Ts...>, Fn>, void_<invoke<Fn, Ts>...>>
  1574. {
  1575. using type = list<invoke<Fn, Ts>...>;
  1576. };
  1577. template <typename... Ts0, typename... Ts1, typename Fn>
  1578. struct transform_<list<list<Ts0...>, list<Ts1...>, Fn>,
  1579. void_<invoke<Fn, Ts0, Ts1>...>>
  1580. {
  1581. using type = list<invoke<Fn, Ts0, Ts1>...>;
  1582. };
  1583. #endif
  1584. } // namespace detail
  1585. /// \endcond
  1586. /// Return a new \c meta::list constructed by transforming all the
  1587. /// elements in \p L with the unary invocable \p Fn. \c transform can
  1588. /// also be called with two lists of the same length and a binary
  1589. /// invocable, in which case it returns a new list constructed with the
  1590. /// results of calling \c Fn with each element in the lists, pairwise.
  1591. /// \par Complexity
  1592. /// `O(N)`.
  1593. /// \ingroup transformation
  1594. #ifdef META_CONCEPT
  1595. template <typename... Args>
  1596. using transform = _t<detail::transform_<Args...>>;
  1597. #else
  1598. template <typename... Args>
  1599. using transform = _t<detail::transform_<list<Args...>>>;
  1600. #endif
  1601. namespace lazy
  1602. {
  1603. /// \sa 'meta::transform'
  1604. /// \ingroup lazy_transformation
  1605. template <typename... Args>
  1606. using transform = defer<transform, Args...>;
  1607. } // namespace lazy
  1608. ///////////////////////////////////////////////////////////////////////////////////////////
  1609. // repeat_n
  1610. /// \cond
  1611. namespace detail
  1612. {
  1613. template <typename T, std::size_t>
  1614. using first_ = T;
  1615. template <typename T, typename Ints>
  1616. struct repeat_n_c_
  1617. {
  1618. };
  1619. template <typename T, std::size_t... Is>
  1620. struct repeat_n_c_<T, index_sequence<Is...>>
  1621. {
  1622. using type = list<first_<T, Is>...>;
  1623. };
  1624. } // namespace detail
  1625. /// \endcond
  1626. /// Generate `list<T,T,T...T>` of size \p N arguments.
  1627. /// \par Complexity
  1628. /// `O(log N)`.
  1629. /// \ingroup list
  1630. template <std::size_t N, typename T = void>
  1631. using repeat_n_c = _t<detail::repeat_n_c_<T, make_index_sequence<N>>>;
  1632. /// Generate `list<T,T,T...T>` of size \p N arguments.
  1633. /// \par Complexity
  1634. /// `O(log N)`.
  1635. /// \ingroup list
  1636. template <META_TYPE_CONSTRAINT(integral) N, typename T = void>
  1637. using repeat_n = repeat_n_c<N::type::value, T>;
  1638. namespace lazy
  1639. {
  1640. /// \sa 'meta::repeat_n'
  1641. /// \ingroup lazy_list
  1642. template <typename N, typename T = void>
  1643. using repeat_n = defer<repeat_n, N, T>;
  1644. /// \sa 'meta::repeat_n_c'
  1645. /// \ingroup lazy_list
  1646. template <std::size_t N, typename T = void>
  1647. using repeat_n_c = defer<repeat_n, meta::size_t<N>, T>;
  1648. } // namespace lazy
  1649. ///////////////////////////////////////////////////////////////////////////////////////////
  1650. // at
  1651. /// \cond
  1652. namespace detail
  1653. {
  1654. #if META_HAS_TYPE_PACK_ELEMENT && !defined(META_DOXYGEN_INVOKED)
  1655. template <typename L, std::size_t N, typename = void>
  1656. struct at_
  1657. {
  1658. };
  1659. template <typename... Ts, std::size_t N>
  1660. struct at_<list<Ts...>, N, void_<__type_pack_element<N, Ts...>>>
  1661. {
  1662. using type = __type_pack_element<N, Ts...>;
  1663. };
  1664. #else
  1665. template <typename VoidPtrs>
  1666. struct at_impl_;
  1667. template <typename... VoidPtrs>
  1668. struct at_impl_<list<VoidPtrs...>>
  1669. {
  1670. static nil_ eval(...);
  1671. template <typename T, typename... Us>
  1672. static T eval(VoidPtrs..., T *, Us *...);
  1673. };
  1674. template <typename L, std::size_t N>
  1675. struct at_
  1676. {
  1677. };
  1678. template <typename... Ts, std::size_t N>
  1679. struct at_<list<Ts...>, N>
  1680. : decltype(at_impl_<repeat_n_c<N, void *>>::eval(static_cast<id<Ts> *>(nullptr)...))
  1681. {
  1682. };
  1683. #endif // META_HAS_TYPE_PACK_ELEMENT
  1684. } // namespace detail
  1685. /// \endcond
  1686. /// Return the \p N th element in the \c meta::list \p L.
  1687. /// \par Complexity
  1688. /// Amortized `O(1)`.
  1689. /// \ingroup list
  1690. template <META_TYPE_CONSTRAINT(list_like) L, std::size_t N>
  1691. using at_c = _t<detail::at_<L, N>>;
  1692. /// Return the \p N th element in the \c meta::list \p L.
  1693. /// \par Complexity
  1694. /// Amortized `O(1)`.
  1695. /// \ingroup list
  1696. template <META_TYPE_CONSTRAINT(list_like) L, META_TYPE_CONSTRAINT(integral) N>
  1697. using at = at_c<L, N::type::value>;
  1698. namespace lazy
  1699. {
  1700. /// \sa 'meta::at'
  1701. /// \ingroup lazy_list
  1702. template <typename L, typename N>
  1703. using at = defer<at, L, N>;
  1704. } // namespace lazy
  1705. ///////////////////////////////////////////////////////////////////////////////////////////
  1706. // drop
  1707. /// \cond
  1708. namespace detail
  1709. {
  1710. ///////////////////////////////////////////////////////////////////////////////////////
  1711. /// drop_impl_
  1712. template <typename VoidPtrs>
  1713. struct drop_impl_
  1714. {
  1715. static nil_ eval(...);
  1716. };
  1717. template <typename... VoidPtrs>
  1718. struct drop_impl_<list<VoidPtrs...>>
  1719. {
  1720. static nil_ eval(...);
  1721. template <typename... Ts>
  1722. static id<list<Ts...>> eval(VoidPtrs..., id<Ts> *...);
  1723. };
  1724. template <>
  1725. struct drop_impl_<list<>>
  1726. {
  1727. template <typename... Ts>
  1728. static id<list<Ts...>> eval(id<Ts> *...);
  1729. };
  1730. template <typename L, std::size_t N>
  1731. struct drop_
  1732. {
  1733. };
  1734. template <typename... Ts, std::size_t N>
  1735. struct drop_<list<Ts...>, N>
  1736. #if META_CXX_VARIABLE_TEMPLATES
  1737. : decltype(drop_impl_<repeat_n_c<N, void *>>::eval(detail::nullptr_v<id<Ts>>...))
  1738. #else
  1739. : decltype(drop_impl_<repeat_n_c<N, void *>>::eval(detail::_nullptr_v<id<Ts>>()...))
  1740. #endif
  1741. {
  1742. };
  1743. } // namespace detail
  1744. /// \endcond
  1745. /// Return a new \c meta::list by removing the first \p N elements from \p L.
  1746. /// \par Complexity
  1747. /// `O(1)`.
  1748. /// \ingroup transformation
  1749. template <META_TYPE_CONSTRAINT(list_like) L, std::size_t N>
  1750. using drop_c = _t<detail::drop_<L, N>>;
  1751. /// Return a new \c meta::list by removing the first \p N elements from \p L.
  1752. /// \par Complexity
  1753. /// `O(1)`.
  1754. /// \ingroup transformation
  1755. template <META_TYPE_CONSTRAINT(list_like) L, META_TYPE_CONSTRAINT(integral) N>
  1756. using drop = drop_c<L, N::type::value>;
  1757. namespace lazy
  1758. {
  1759. /// \sa 'meta::drop'
  1760. /// \ingroup lazy_transformation
  1761. template <typename L, typename N>
  1762. using drop = defer<drop, L, N>;
  1763. } // namespace lazy
  1764. ///////////////////////////////////////////////////////////////////////////////////////////
  1765. // front
  1766. /// \cond
  1767. namespace detail
  1768. {
  1769. template <typename L>
  1770. struct front_
  1771. {
  1772. };
  1773. template <typename Head, typename... Tail>
  1774. struct front_<list<Head, Tail...>>
  1775. {
  1776. using type = Head;
  1777. };
  1778. } // namespace detail
  1779. /// \endcond
  1780. /// Return the first element in \c meta::list \p L.
  1781. /// \par Complexity
  1782. /// `O(1)`.
  1783. /// \ingroup list
  1784. template <META_TYPE_CONSTRAINT(list_like) L>
  1785. using front = _t<detail::front_<L>>;
  1786. namespace lazy
  1787. {
  1788. /// \sa 'meta::front'
  1789. /// \ingroup lazy_list
  1790. template <typename L>
  1791. using front = defer<front, L>;
  1792. } // namespace lazy
  1793. ///////////////////////////////////////////////////////////////////////////////////////////
  1794. // back
  1795. /// \cond
  1796. namespace detail
  1797. {
  1798. template <typename L>
  1799. struct back_
  1800. {
  1801. };
  1802. template <typename Head, typename... Tail>
  1803. struct back_<list<Head, Tail...>>
  1804. {
  1805. using type = at_c<list<Head, Tail...>, sizeof...(Tail)>;
  1806. };
  1807. } // namespace detail
  1808. /// \endcond
  1809. /// Return the last element in \c meta::list \p L.
  1810. /// \par Complexity
  1811. /// Amortized `O(1)`.
  1812. /// \ingroup list
  1813. template <META_TYPE_CONSTRAINT(list_like) L>
  1814. using back = _t<detail::back_<L>>;
  1815. namespace lazy
  1816. {
  1817. /// \sa 'meta::back'
  1818. /// \ingroup lazy_list
  1819. template <typename L>
  1820. using back = defer<back, L>;
  1821. } // namespace lazy
  1822. ///////////////////////////////////////////////////////////////////////////////////////////
  1823. // push_front
  1824. /// Return a new \c meta::list by adding the element \c T to the front of \p L.
  1825. /// \par Complexity
  1826. /// `O(1)`.
  1827. /// \ingroup transformation
  1828. template <META_TYPE_CONSTRAINT(list_like) L, typename... Ts>
  1829. using push_front = apply<bind_front<quote<list>, Ts...>, L>;
  1830. namespace lazy
  1831. {
  1832. /// \sa 'meta::push_front'
  1833. /// \ingroup lazy_transformation
  1834. template <typename... Ts>
  1835. using push_front = defer<push_front, Ts...>;
  1836. } // namespace lazy
  1837. ///////////////////////////////////////////////////////////////////////////////////////////
  1838. // pop_front
  1839. /// \cond
  1840. namespace detail
  1841. {
  1842. template <typename L>
  1843. struct pop_front_
  1844. {
  1845. };
  1846. template <typename Head, typename... L>
  1847. struct pop_front_<list<Head, L...>>
  1848. {
  1849. using type = list<L...>;
  1850. };
  1851. } // namespace detail
  1852. /// \endcond
  1853. /// Return a new \c meta::list by removing the first element from the
  1854. /// front of \p L.
  1855. /// \par Complexity
  1856. /// `O(1)`.
  1857. /// \ingroup transformation
  1858. template <META_TYPE_CONSTRAINT(list_like) L>
  1859. using pop_front = _t<detail::pop_front_<L>>;
  1860. namespace lazy
  1861. {
  1862. /// \sa 'meta::pop_front'
  1863. /// \ingroup lazy_transformation
  1864. template <typename L>
  1865. using pop_front = defer<pop_front, L>;
  1866. } // namespace lazy
  1867. ///////////////////////////////////////////////////////////////////////////////////////////
  1868. // push_back
  1869. /// Return a new \c meta::list by adding the element \c T to the back of \p L.
  1870. /// \par Complexity
  1871. /// `O(1)`.
  1872. /// \note \c pop_back not provided because it cannot be made to meet the
  1873. /// complexity guarantees one would expect.
  1874. /// \ingroup transformation
  1875. template <META_TYPE_CONSTRAINT(list_like) L, typename... Ts>
  1876. using push_back = apply<bind_back<quote<list>, Ts...>, L>;
  1877. namespace lazy
  1878. {
  1879. /// \sa 'meta::push_back'
  1880. /// \ingroup lazy_transformation
  1881. template <typename... Ts>
  1882. using push_back = defer<push_back, Ts...>;
  1883. } // namespace lazy
  1884. /// \cond
  1885. namespace detail
  1886. {
  1887. template <typename T, typename U>
  1888. using min_ = if_<less<U, T>, U, T>;
  1889. template <typename T, typename U>
  1890. using max_ = if_<less<U, T>, T, U>;
  1891. } // namespace detail
  1892. /// \endcond
  1893. /// An integral constant wrapper around the minimum of `Ts::type::value...`
  1894. /// \ingroup math
  1895. template <META_TYPE_CONSTRAINT(integral)... Ts>
  1896. using min_ = fold<pop_front<list<Ts...>>, front<list<Ts...>>, quote<detail::min_>>;
  1897. template <typename... Ts>
  1898. using min = min_<Ts...>;
  1899. /// An integral constant wrapper around the maximum of `Ts::type::value...`
  1900. /// \ingroup math
  1901. template <META_TYPE_CONSTRAINT(integral)... Ts>
  1902. using max_ = fold<pop_front<list<Ts...>>, front<list<Ts...>>, quote<detail::max_>>;
  1903. template <typename... Ts>
  1904. using max = max_<Ts...>;
  1905. namespace lazy
  1906. {
  1907. /// \sa 'meta::min'
  1908. /// \ingroup lazy_math
  1909. template <typename... Ts>
  1910. using min = defer<min, Ts...>;
  1911. /// \sa 'meta::max'
  1912. /// \ingroup lazy_math
  1913. template <typename... Ts>
  1914. using max = defer<max, Ts...>;
  1915. } // namespace lazy
  1916. ///////////////////////////////////////////////////////////////////////////////////////////
  1917. // empty
  1918. /// An Boolean integral constant wrapper around \c true if \p L is an
  1919. /// empty type list; \c false, otherwise.
  1920. /// \par Complexity
  1921. /// `O(1)`.
  1922. /// \ingroup list
  1923. template <META_TYPE_CONSTRAINT(list_like) L>
  1924. using empty = bool_<0 == size<L>::type::value>;
  1925. namespace lazy
  1926. {
  1927. /// \sa 'meta::empty'
  1928. /// \ingroup lazy_list
  1929. template <typename L>
  1930. using empty = defer<empty, L>;
  1931. } // namespace lazy
  1932. ///////////////////////////////////////////////////////////////////////////////////////////
  1933. // pair
  1934. /// A list with exactly two elements
  1935. /// \ingroup list
  1936. template <typename F, typename S>
  1937. using pair = list<F, S>;
  1938. /// Retrieve the first element of the \c pair \p Pair
  1939. /// \ingroup list
  1940. template <typename Pair>
  1941. using first = front<Pair>;
  1942. /// Retrieve the first element of the \c pair \p Pair
  1943. /// \ingroup list
  1944. template <typename Pair>
  1945. using second = front<pop_front<Pair>>;
  1946. namespace lazy
  1947. {
  1948. /// \sa 'meta::first'
  1949. /// \ingroup lazy_list
  1950. template <typename Pair>
  1951. using first = defer<first, Pair>;
  1952. /// \sa 'meta::second'
  1953. /// \ingroup lazy_list
  1954. template <typename Pair>
  1955. using second = defer<second, Pair>;
  1956. } // namespace lazy
  1957. ///////////////////////////////////////////////////////////////////////////////////////////
  1958. // find_index
  1959. /// \cond
  1960. namespace detail
  1961. {
  1962. // With thanks to Peter Dimov:
  1963. constexpr std::size_t find_index_i_(bool const *const first, bool const *const last,
  1964. std::size_t N = 0)
  1965. {
  1966. return first == last ? npos::value
  1967. : *first ? N : find_index_i_(first + 1, last, N + 1);
  1968. }
  1969. template <typename L, typename T>
  1970. struct find_index_
  1971. {
  1972. };
  1973. template <typename V>
  1974. struct find_index_<list<>, V>
  1975. {
  1976. using type = npos;
  1977. };
  1978. template <typename... T, typename V>
  1979. struct find_index_<list<T...>, V>
  1980. {
  1981. #ifdef META_WORKAROUND_LLVM_28385
  1982. static constexpr bool s_v[sizeof...(T)] = {META_IS_SAME(T, V)...};
  1983. #else
  1984. static constexpr bool s_v[] = {META_IS_SAME(T, V)...};
  1985. #endif
  1986. using type = size_t<find_index_i_(s_v, s_v + sizeof...(T))>;
  1987. };
  1988. } // namespace detail
  1989. /// \endcond
  1990. /// Finds the index of the first occurrence of the type \p T within the list \p L.
  1991. /// Returns `#meta::npos` if the type \p T was not found.
  1992. /// \par Complexity
  1993. /// `O(N)`.
  1994. /// \ingroup query
  1995. /// \sa `meta::npos`
  1996. template <META_TYPE_CONSTRAINT(list_like) L, typename T>
  1997. using find_index = _t<detail::find_index_<L, T>>;
  1998. namespace lazy
  1999. {
  2000. /// \sa 'meta::find_index'
  2001. /// \ingroup lazy_query
  2002. template <typename L, typename T>
  2003. using find_index = defer<find_index, L, T>;
  2004. } // namespace lazy
  2005. ///////////////////////////////////////////////////////////////////////////////////////////
  2006. // reverse_find_index
  2007. /// \cond
  2008. namespace detail
  2009. {
  2010. // With thanks to Peter Dimov:
  2011. constexpr std::size_t reverse_find_index_i_(bool const *const first,
  2012. bool const *const last, std::size_t N)
  2013. {
  2014. return first == last
  2015. ? npos::value
  2016. : *(last - 1) ? N - 1 : reverse_find_index_i_(first, last - 1, N - 1);
  2017. }
  2018. template <typename L, typename T>
  2019. struct reverse_find_index_
  2020. {
  2021. };
  2022. template <typename V>
  2023. struct reverse_find_index_<list<>, V>
  2024. {
  2025. using type = npos;
  2026. };
  2027. template <typename... T, typename V>
  2028. struct reverse_find_index_<list<T...>, V>
  2029. {
  2030. #ifdef META_WORKAROUND_LLVM_28385
  2031. static constexpr bool s_v[sizeof...(T)] = {META_IS_SAME(T, V)...};
  2032. #else
  2033. static constexpr bool s_v[] = {META_IS_SAME(T, V)...};
  2034. #endif
  2035. using type = size_t<reverse_find_index_i_(s_v, s_v + sizeof...(T), sizeof...(T))>;
  2036. };
  2037. } // namespace detail
  2038. /// \endcond
  2039. /// Finds the index of the last occurrence of the type \p T within the
  2040. /// list \p L. Returns `#meta::npos` if the type \p T was not found.
  2041. /// \par Complexity
  2042. /// `O(N)`.
  2043. /// \ingroup query
  2044. /// \sa `#meta::npos`
  2045. template <META_TYPE_CONSTRAINT(list_like) L, typename T>
  2046. using reverse_find_index = _t<detail::reverse_find_index_<L, T>>;
  2047. namespace lazy
  2048. {
  2049. /// \sa 'meta::reverse_find_index'
  2050. /// \ingroup lazy_query
  2051. template <typename L, typename T>
  2052. using reverse_find_index = defer<reverse_find_index, L, T>;
  2053. } // namespace lazy
  2054. ////////////////////////////////////////////////////////////////////////////////////
  2055. // find
  2056. /// Return the tail of the list \p L starting at the first occurrence of
  2057. /// \p T, if any such element exists; the empty list, otherwise.
  2058. /// \par Complexity
  2059. /// `O(N)`.
  2060. /// \ingroup query
  2061. template <META_TYPE_CONSTRAINT(list_like) L, typename T>
  2062. using find = drop<L, min<find_index<L, T>, size<L>>>;
  2063. namespace lazy
  2064. {
  2065. /// \sa 'meta::find'
  2066. /// \ingroup lazy_query
  2067. template <typename L, typename T>
  2068. using find = defer<find, L, T>;
  2069. } // namespace lazy
  2070. ////////////////////////////////////////////////////////////////////////////////////
  2071. // reverse_find
  2072. /// \cond
  2073. namespace detail
  2074. {
  2075. template <typename L, typename T, typename State = list<>>
  2076. struct reverse_find_
  2077. {
  2078. };
  2079. template <typename T, typename State>
  2080. struct reverse_find_<list<>, T, State>
  2081. {
  2082. using type = State;
  2083. };
  2084. template <typename Head, typename... L, typename T, typename State>
  2085. struct reverse_find_<list<Head, L...>, T, State> : reverse_find_<list<L...>, T, State>
  2086. {
  2087. };
  2088. template <typename... L, typename T, typename State>
  2089. struct reverse_find_<list<T, L...>, T, State>
  2090. : reverse_find_<list<L...>, T, list<T, L...>>
  2091. {
  2092. };
  2093. } // namespace detail
  2094. /// \endcond
  2095. /// Return the tail of the list \p L starting at the last occurrence of \p T, if any such
  2096. /// element exists; the empty list, otherwise.
  2097. /// \par Complexity
  2098. /// `O(N)`.
  2099. /// \ingroup query
  2100. template <META_TYPE_CONSTRAINT(list_like) L, typename T>
  2101. using reverse_find = drop<L, min<reverse_find_index<L, T>, size<L>>>;
  2102. namespace lazy
  2103. {
  2104. /// \sa 'meta::rfind'
  2105. /// \ingroup lazy_query
  2106. template <typename L, typename T>
  2107. using reverse_find = defer<reverse_find, L, T>;
  2108. } // namespace lazy
  2109. ///////////////////////////////////////////////////////////////////////////////////////////
  2110. // find_if
  2111. /// \cond
  2112. namespace detail
  2113. {
  2114. #ifdef META_CONCEPT
  2115. template <typename L, typename Fn>
  2116. struct find_if_
  2117. {
  2118. };
  2119. template <typename Fn>
  2120. struct find_if_<list<>, Fn>
  2121. {
  2122. using type = list<>;
  2123. };
  2124. template <typename Head, typename... L, typename Fn>
  2125. requires integral<invoke<Fn, Head>>
  2126. struct find_if_<list<Head, L...>, Fn>
  2127. : if_<invoke<Fn, Head>, id<list<Head, L...>>, find_if_<list<L...>, Fn>>
  2128. {
  2129. };
  2130. #else
  2131. constexpr bool const *find_if_i_(bool const *const begin, bool const *const end)
  2132. {
  2133. return begin == end || *begin ? begin : find_if_i_(begin + 1, end);
  2134. }
  2135. template <typename L, typename Fn, typename = void>
  2136. struct find_if_
  2137. {
  2138. };
  2139. template <typename Fn>
  2140. struct find_if_<list<>, Fn>
  2141. {
  2142. using type = list<>;
  2143. };
  2144. template <typename... L, typename Fn>
  2145. struct find_if_<list<L...>, Fn,
  2146. void_<integer_sequence<bool, bool(invoke<Fn, L>::type::value)...>>>
  2147. {
  2148. #ifdef META_WORKAROUND_LLVM_28385
  2149. static constexpr bool s_v[sizeof...(L)] = {invoke<Fn, L>::type::value...};
  2150. #else
  2151. static constexpr bool s_v[] = {invoke<Fn, L>::type::value...};
  2152. #endif
  2153. using type =
  2154. drop_c<list<L...>, detail::find_if_i_(s_v, s_v + sizeof...(L)) - s_v>;
  2155. };
  2156. #endif
  2157. } // namespace detail
  2158. /// \endcond
  2159. /// Return the tail of the list \p L starting at the first element `A`
  2160. /// such that `invoke<Fn, A>::%value` is \c true, if any such element
  2161. /// exists; the empty list, otherwise.
  2162. /// \par Complexity
  2163. /// `O(N)`.
  2164. /// \ingroup query
  2165. template <META_TYPE_CONSTRAINT(list_like) L, META_TYPE_CONSTRAINT(invocable) Fn>
  2166. using find_if = _t<detail::find_if_<L, Fn>>;
  2167. namespace lazy
  2168. {
  2169. /// \sa 'meta::find_if'
  2170. /// \ingroup lazy_query
  2171. template <typename L, typename Fn>
  2172. using find_if = defer<find_if, L, Fn>;
  2173. } // namespace lazy
  2174. ////////////////////////////////////////////////////////////////////////////////////
  2175. // reverse_find_if
  2176. /// \cond
  2177. namespace detail
  2178. {
  2179. #ifdef META_CONCEPT
  2180. template <typename L, typename Fn, typename State = list<>>
  2181. struct reverse_find_if_
  2182. {
  2183. };
  2184. template <typename Fn, typename State>
  2185. struct reverse_find_if_<list<>, Fn, State>
  2186. {
  2187. using type = State;
  2188. };
  2189. template <typename Head, typename... L, typename Fn, typename State>
  2190. requires integral<invoke<Fn, Head>>
  2191. struct reverse_find_if_<list<Head, L...>, Fn, State>
  2192. : reverse_find_if_<list<L...>, Fn, if_<invoke<Fn, Head>, list<Head, L...>, State>>
  2193. {
  2194. };
  2195. #else
  2196. constexpr bool const *reverse_find_if_i_(bool const *const begin, bool const *const pos,
  2197. bool const *const end)
  2198. {
  2199. return begin == pos
  2200. ? end
  2201. : *(pos - 1) ? pos - 1 : reverse_find_if_i_(begin, pos - 1, end);
  2202. }
  2203. template <typename L, typename Fn, typename = void>
  2204. struct reverse_find_if_
  2205. {
  2206. };
  2207. template <typename Fn>
  2208. struct reverse_find_if_<list<>, Fn>
  2209. {
  2210. using type = list<>;
  2211. };
  2212. template <typename... L, typename Fn>
  2213. struct reverse_find_if_<
  2214. list<L...>, Fn,
  2215. void_<integer_sequence<bool, bool(invoke<Fn, L>::type::value)...>>>
  2216. {
  2217. #ifdef META_WORKAROUND_LLVM_28385
  2218. static constexpr bool s_v[sizeof...(L)] = {invoke<Fn, L>::type::value...};
  2219. #else
  2220. static constexpr bool s_v[] = {invoke<Fn, L>::type::value...};
  2221. #endif
  2222. using type =
  2223. drop_c<list<L...>, detail::reverse_find_if_i_(s_v, s_v + sizeof...(L),
  2224. s_v + sizeof...(L)) -
  2225. s_v>;
  2226. };
  2227. #endif
  2228. } // namespace detail
  2229. /// \endcond
  2230. /// Return the tail of the list \p L starting at the last element `A`
  2231. /// such that `invoke<Fn, A>::%value` is \c true, if any such element
  2232. /// exists; the empty list, otherwise.
  2233. /// \par Complexity
  2234. /// `O(N)`.
  2235. /// \ingroup query
  2236. template <META_TYPE_CONSTRAINT(list_like) L, META_TYPE_CONSTRAINT(invocable) Fn>
  2237. using reverse_find_if = _t<detail::reverse_find_if_<L, Fn>>;
  2238. namespace lazy
  2239. {
  2240. /// \sa 'meta::rfind_if'
  2241. /// \ingroup lazy_query
  2242. template <typename L, typename Fn>
  2243. using reverse_find_if = defer<reverse_find_if, L, Fn>;
  2244. } // namespace lazy
  2245. ///////////////////////////////////////////////////////////////////////////////////////////
  2246. // replace
  2247. /// \cond
  2248. namespace detail
  2249. {
  2250. template <typename L, typename T, typename U>
  2251. struct replace_
  2252. {
  2253. };
  2254. template <typename... L, typename T, typename U>
  2255. struct replace_<list<L...>, T, U>
  2256. {
  2257. using type = list<if_c<META_IS_SAME(T, L), U, L>...>;
  2258. };
  2259. } // namespace detail
  2260. /// \endcond
  2261. /// Return a new \c meta::list where all instances of type \p T have
  2262. /// been replaced with \p U.
  2263. /// \par Complexity
  2264. /// `O(N)`.
  2265. /// \ingroup transformation
  2266. template <META_TYPE_CONSTRAINT(list_like) L, typename T, typename U>
  2267. using replace = _t<detail::replace_<L, T, U>>;
  2268. namespace lazy
  2269. {
  2270. /// \sa 'meta::replace'
  2271. /// \ingroup lazy_transformation
  2272. template <typename L, typename T, typename U>
  2273. using replace = defer<replace, T, U>;
  2274. } // namespace lazy
  2275. ///////////////////////////////////////////////////////////////////////////////////////////
  2276. // replace_if
  2277. /// \cond
  2278. namespace detail
  2279. {
  2280. #ifdef META_CONCEPT
  2281. template <typename L, typename C, typename U>
  2282. struct replace_if_
  2283. {
  2284. };
  2285. template <typename... L, typename C, typename U>
  2286. requires and_v<integral<invoke<C, L>>...>
  2287. struct replace_if_<list<L...>, C, U>
  2288. {
  2289. using type = list<if_<invoke<C, L>, U, L>...>;
  2290. };
  2291. #else
  2292. template <typename L, typename C, typename U, typename = void>
  2293. struct replace_if_
  2294. {
  2295. };
  2296. template <typename... L, typename C, typename U>
  2297. struct replace_if_<list<L...>, C, U,
  2298. void_<integer_sequence<bool, bool(invoke<C, L>::type::value)...>>>
  2299. {
  2300. using type = list<if_<invoke<C, L>, U, L>...>;
  2301. };
  2302. #endif
  2303. } // namespace detail
  2304. /// \endcond
  2305. /// Return a new \c meta::list where all elements \c A of the list \p L
  2306. /// for which `invoke<C,A>::%value` is \c true have been replaced with
  2307. /// \p U.
  2308. /// \par Complexity
  2309. /// `O(N)`.
  2310. /// \ingroup transformation
  2311. template <META_TYPE_CONSTRAINT(list_like) L, typename C, typename U>
  2312. using replace_if = _t<detail::replace_if_<L, C, U>>;
  2313. namespace lazy
  2314. {
  2315. /// \sa 'meta::replace_if'
  2316. /// \ingroup lazy_transformation
  2317. template <typename L, typename C, typename U>
  2318. using replace_if = defer<replace_if, C, U>;
  2319. } // namespace lazy
  2320. ///////////////////////////////////////////////////////////////////////////////////////
  2321. // count
  2322. namespace detail
  2323. {
  2324. template <typename, typename>
  2325. struct count_
  2326. {
  2327. };
  2328. #if (defined(META_CONCEPT) || META_CXX_VARIABLE_TEMPLATES) && META_CXX_FOLD_EXPRESSIONS
  2329. template <typename... Ts, typename T>
  2330. struct count_<list<Ts...>, T>
  2331. {
  2332. using type = meta::size_t<((std::size_t)META_IS_SAME(T, Ts) + ...)>;
  2333. };
  2334. #else
  2335. constexpr std::size_t count_i_(bool const *const begin, bool const *const end,
  2336. std::size_t n)
  2337. {
  2338. return begin == end ? n : detail::count_i_(begin + 1, end, n + *begin);
  2339. }
  2340. template <typename T>
  2341. struct count_<list<>, T>
  2342. {
  2343. using type = meta::size_t<0>;
  2344. };
  2345. template <typename... L, typename T>
  2346. struct count_<list<L...>, T>
  2347. {
  2348. #ifdef META_WORKAROUND_LLVM_28385
  2349. static constexpr bool s_v[sizeof...(L)] = {META_IS_SAME(T, L)...};
  2350. #else
  2351. static constexpr bool s_v[] = {META_IS_SAME(T, L)...};
  2352. #endif
  2353. using type = meta::size_t<detail::count_i_(s_v, s_v + sizeof...(L), 0u)>;
  2354. };
  2355. #endif
  2356. } // namespace detail
  2357. /// Count the number of times a type \p T appears in the list \p L.
  2358. /// \par Complexity
  2359. /// `O(N)`.
  2360. /// \ingroup query
  2361. template <META_TYPE_CONSTRAINT(list_like) L, typename T>
  2362. using count = _t<detail::count_<L, T>>;
  2363. namespace lazy
  2364. {
  2365. /// \sa `meta::count`
  2366. /// \ingroup lazy_query
  2367. template <typename L, typename T>
  2368. using count = defer<count, L, T>;
  2369. } // namespace lazy
  2370. ///////////////////////////////////////////////////////////////////////////////////////
  2371. // count_if
  2372. namespace detail
  2373. {
  2374. #if defined(META_CONCEPT) && META_CXX_FOLD_EXPRESSIONS
  2375. template <typename, typename>
  2376. struct count_if_
  2377. {
  2378. };
  2379. template <typename... Ts, typename Fn>
  2380. requires (integral<invoke<Fn, Ts>> && ...)
  2381. struct count_if_<list<Ts...>, Fn>
  2382. {
  2383. using type = meta::size_t<((std::size_t)(bool)_v<invoke<Fn, Ts>> + ...)>;
  2384. };
  2385. #else
  2386. template <typename L, typename Fn, typename = void>
  2387. struct count_if_
  2388. {
  2389. };
  2390. template <typename Fn>
  2391. struct count_if_<list<>, Fn>
  2392. {
  2393. using type = meta::size_t<0>;
  2394. };
  2395. template <typename... L, typename Fn>
  2396. struct count_if_<list<L...>, Fn,
  2397. void_<integer_sequence<bool, bool(invoke<Fn, L>::type::value)...>>>
  2398. {
  2399. #if META_CXX_FOLD_EXPRESSIONS
  2400. using type = meta::size_t<((std::size_t)(bool)invoke<Fn, L>::type::value + ...)>;
  2401. #else
  2402. #ifdef META_WORKAROUND_LLVM_28385
  2403. static constexpr bool s_v[sizeof...(L)] = {invoke<Fn, L>::type::value...};
  2404. #else
  2405. static constexpr bool s_v[] = {invoke<Fn, L>::type::value...};
  2406. #endif
  2407. using type = meta::size_t<detail::count_i_(s_v, s_v + sizeof...(L), 0u)>;
  2408. #endif // META_CXX_FOLD_EXPRESSIONS
  2409. };
  2410. #endif // META_CONCEPT
  2411. } // namespace detail
  2412. /// Count the number of times the predicate \p Fn evaluates to true for all the elements in
  2413. /// the list \p L.
  2414. /// \par Complexity
  2415. /// `O(N)`.
  2416. /// \ingroup query
  2417. template <META_TYPE_CONSTRAINT(list_like) L, META_TYPE_CONSTRAINT(invocable) Fn>
  2418. using count_if = _t<detail::count_if_<L, Fn>>;
  2419. namespace lazy
  2420. {
  2421. /// \sa `meta::count_if`
  2422. /// \ingroup lazy_query
  2423. template <typename L, typename Fn>
  2424. using count_if = defer<count_if, L, Fn>;
  2425. } // namespace lazy
  2426. ///////////////////////////////////////////////////////////////////////////////////////////
  2427. // filter
  2428. /// \cond
  2429. namespace detail
  2430. {
  2431. template <typename Pred>
  2432. struct filter_
  2433. {
  2434. template <typename A>
  2435. using invoke = if_c<invoke<Pred, A>::type::value, list<A>, list<>>;
  2436. };
  2437. } // namespace detail
  2438. /// \endcond
  2439. /// Returns a new meta::list where only those elements of \p L that satisfy the
  2440. /// Callable \p Pred such that `invoke<Pred,A>::%value` is \c true are present.
  2441. /// That is, those elements that don't satisfy the \p Pred are "removed".
  2442. /// \par Complexity
  2443. /// `O(N)`.
  2444. /// \ingroup transformation
  2445. template <typename L, typename Pred>
  2446. using filter = join<transform<L, detail::filter_<Pred>>>;
  2447. namespace lazy
  2448. {
  2449. /// \sa 'meta::filter'
  2450. /// \ingroup lazy_transformation
  2451. template <typename L, typename Fn>
  2452. using filter = defer<filter, L, Fn>;
  2453. } // namespace lazy
  2454. ///////////////////////////////////////////////////////////////////////////////////////////
  2455. // static_const
  2456. ///\cond
  2457. namespace detail
  2458. {
  2459. template <typename T>
  2460. struct static_const
  2461. {
  2462. static constexpr T value{};
  2463. };
  2464. // Avoid potential ODR violations with global objects:
  2465. template <typename T>
  2466. constexpr T static_const<T>::value;
  2467. } // namespace detail
  2468. ///\endcond
  2469. ///////////////////////////////////////////////////////////////////////////////////////////
  2470. // for_each
  2471. /// \cond
  2472. namespace detail
  2473. {
  2474. struct for_each_fn
  2475. {
  2476. template <class Fn, class... Args>
  2477. constexpr auto operator()(list<Args...>, Fn f) const -> Fn
  2478. {
  2479. return (void)std::initializer_list<int>{((void)f(Args{}), 0)...}, f;
  2480. }
  2481. };
  2482. } // namespace detail
  2483. /// \endcond
  2484. #if META_CXX_INLINE_VARIABLES
  2485. /// `for_each(L, Fn)` calls the \p Fn for each
  2486. /// argument in the \p L.
  2487. /// \ingroup runtime
  2488. inline constexpr detail::for_each_fn for_each{};
  2489. #else
  2490. ///\cond
  2491. namespace
  2492. {
  2493. /// \endcond
  2494. /// `for_each(List, UnaryFunction)` calls the \p UnaryFunction for each
  2495. /// argument in the \p List.
  2496. /// \ingroup runtime
  2497. constexpr auto &&for_each = detail::static_const<detail::for_each_fn>::value;
  2498. /// \cond
  2499. }
  2500. /// \endcond
  2501. #endif
  2502. ///////////////////////////////////////////////////////////////////////////////////////////
  2503. // transpose
  2504. /// Given a list of lists of types \p ListOfLists, transpose the elements from the lists.
  2505. /// \par Complexity
  2506. /// `O(N * M)`, where `N` is the size of the outer list, and
  2507. /// `M` is the size of the inner lists.
  2508. /// \ingroup transformation
  2509. template <META_TYPE_CONSTRAINT(list_like) ListOfLists>
  2510. using transpose = fold<ListOfLists, repeat_n<size<front<ListOfLists>>, list<>>,
  2511. bind_back<quote<transform>, quote<push_back>>>;
  2512. namespace lazy
  2513. {
  2514. /// \sa 'meta::transpose'
  2515. /// \ingroup lazy_transformation
  2516. template <typename ListOfLists>
  2517. using transpose = defer<transpose, ListOfLists>;
  2518. } // namespace lazy
  2519. ///////////////////////////////////////////////////////////////////////////////////////////
  2520. // zip_with
  2521. /// Given a list of lists of types \p ListOfLists and an invocable \p Fn, construct a new
  2522. /// list by calling \p Fn with the elements from the lists pairwise.
  2523. /// \par Complexity
  2524. /// `O(N * M)`, where `N` is the size of the outer list, and
  2525. /// `M` is the size of the inner lists.
  2526. /// \ingroup transformation
  2527. template <META_TYPE_CONSTRAINT(invocable) Fn, META_TYPE_CONSTRAINT(list_like) ListOfLists>
  2528. using zip_with = transform<transpose<ListOfLists>, uncurry<Fn>>;
  2529. namespace lazy
  2530. {
  2531. /// \sa 'meta::zip_with'
  2532. /// \ingroup lazy_transformation
  2533. template <typename Fn, typename ListOfLists>
  2534. using zip_with = defer<zip_with, Fn, ListOfLists>;
  2535. } // namespace lazy
  2536. ///////////////////////////////////////////////////////////////////////////////////////////
  2537. // zip
  2538. /// Given a list of lists of types \p ListOfLists, construct a new list by grouping the
  2539. /// elements from the lists pairwise into `meta::list`s.
  2540. /// \par Complexity
  2541. /// `O(N * M)`, where `N` is the size of the outer list, and `M`
  2542. /// is the size of the inner lists.
  2543. /// \ingroup transformation
  2544. template <META_TYPE_CONSTRAINT(list_like) ListOfLists>
  2545. using zip = transpose<ListOfLists>;
  2546. namespace lazy
  2547. {
  2548. /// \sa 'meta::zip'
  2549. /// \ingroup lazy_transformation
  2550. template <typename ListOfLists>
  2551. using zip = defer<zip, ListOfLists>;
  2552. } // namespace lazy
  2553. ///////////////////////////////////////////////////////////////////////////////////////////
  2554. // as_list
  2555. /// \cond
  2556. namespace detail
  2557. {
  2558. template <typename T>
  2559. using uncvref_t = _t<std::remove_cv<_t<std::remove_reference<T>>>>;
  2560. // Indirection here needed to avoid Core issue 1430
  2561. // https://wg21.link/cwg1430
  2562. template <typename Sequence>
  2563. struct as_list_ : lazy::invoke<uncurry<quote<list>>, Sequence>
  2564. {
  2565. };
  2566. } // namespace detail
  2567. /// \endcond
  2568. /// Turn a type into an instance of \c meta::list in a way determined by
  2569. /// \c meta::apply.
  2570. /// \ingroup list
  2571. template <typename Sequence>
  2572. using as_list = _t<detail::as_list_<detail::uncvref_t<Sequence>>>;
  2573. namespace lazy
  2574. {
  2575. /// \sa 'meta::as_list'
  2576. /// \ingroup lazy_list
  2577. template <typename Sequence>
  2578. using as_list = defer<as_list, Sequence>;
  2579. } // namespace lazy
  2580. ///////////////////////////////////////////////////////////////////////////////////////////
  2581. // reverse
  2582. /// \cond
  2583. namespace detail
  2584. {
  2585. template <typename L, typename State = list<>>
  2586. struct reverse_ : lazy::fold<L, State, quote<push_front>>
  2587. {
  2588. };
  2589. template <typename T0, typename T1, typename T2, typename T3, typename T4, typename T5,
  2590. typename T6, typename T7, typename T8, typename T9, typename... Ts,
  2591. typename... Us>
  2592. struct reverse_<list<T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, Ts...>, list<Us...>>
  2593. : reverse_<list<Ts...>, list<T9, T8, T7, T6, T5, T4, T3, T2, T1, T0, Us...>>
  2594. {
  2595. };
  2596. }
  2597. /// \endcond
  2598. /// Return a new \c meta::list by reversing the elements in the list \p L.
  2599. /// \par Complexity
  2600. /// `O(N)`.
  2601. /// \ingroup transformation
  2602. template <META_TYPE_CONSTRAINT(list_like) L>
  2603. using reverse = _t<detail::reverse_<L>>;
  2604. namespace lazy
  2605. {
  2606. /// \sa 'meta::reverse'
  2607. /// \ingroup lazy_transformation
  2608. template <typename L>
  2609. using reverse = defer<reverse, L>;
  2610. } // namespace lazy
  2611. /// Logically negate the result of invocable \p Fn.
  2612. /// \ingroup trait
  2613. template <META_TYPE_CONSTRAINT(invocable) Fn>
  2614. using not_fn = compose<quote<not_>, Fn>;
  2615. namespace lazy
  2616. {
  2617. /// \sa 'meta::not_fn'
  2618. /// \ingroup lazy_trait
  2619. template <typename Fn>
  2620. using not_fn = defer<not_fn, Fn>;
  2621. } // namespace lazy
  2622. ///////////////////////////////////////////////////////////////////////////////////////////
  2623. // all_of
  2624. /// A Boolean integral constant wrapper around \c true if `invoke<Fn, A>::%value` is \c true
  2625. /// for all elements \c A in \c meta::list \p L; \c false, otherwise.
  2626. /// \par Complexity
  2627. /// `O(N)`.
  2628. /// \ingroup query
  2629. template <META_TYPE_CONSTRAINT(list_like) L, META_TYPE_CONSTRAINT(invocable) Fn>
  2630. using all_of = empty<find_if<L, not_fn<Fn>>>;
  2631. namespace lazy
  2632. {
  2633. /// \sa 'meta::all_of'
  2634. /// \ingroup lazy_query
  2635. template <typename L, typename Fn>
  2636. using all_of = defer<all_of, L, Fn>;
  2637. } // namespace lazy
  2638. ///////////////////////////////////////////////////////////////////////////////////////////
  2639. // any_of
  2640. /// A Boolean integral constant wrapper around \c true if `invoke<Fn, A>::%value` is
  2641. /// \c true for any element \c A in \c meta::list \p L; \c false, otherwise.
  2642. /// \par Complexity
  2643. /// `O(N)`.
  2644. /// \ingroup query
  2645. template <META_TYPE_CONSTRAINT(list_like) L, META_TYPE_CONSTRAINT(invocable) Fn>
  2646. using any_of = not_<empty<find_if<L, Fn>>>;
  2647. namespace lazy
  2648. {
  2649. /// \sa 'meta::any_of'
  2650. /// \ingroup lazy_query
  2651. template <typename L, typename Fn>
  2652. using any_of = defer<any_of, L, Fn>;
  2653. } // namespace lazy
  2654. ///////////////////////////////////////////////////////////////////////////////////////////
  2655. // none_of
  2656. /// A Boolean integral constant wrapper around \c true if `invoke<Fn, A>::%value` is
  2657. /// \c false for all elements \c A in \c meta::list \p L; \c false, otherwise.
  2658. /// \par Complexity
  2659. /// `O(N)`.
  2660. /// \ingroup query
  2661. template <META_TYPE_CONSTRAINT(list_like) L, META_TYPE_CONSTRAINT(invocable) Fn>
  2662. using none_of = empty<find_if<L, Fn>>;
  2663. namespace lazy
  2664. {
  2665. /// \sa 'meta::none_of'
  2666. /// \ingroup lazy_query
  2667. template <typename L, META_TYPE_CONSTRAINT(invocable) Fn>
  2668. using none_of = defer<none_of, L, Fn>;
  2669. } // namespace lazy
  2670. ///////////////////////////////////////////////////////////////////////////////////////////
  2671. // in
  2672. /// A Boolean integral constant wrapper around \c true if there is at least one occurrence
  2673. /// of \p T in \p L.
  2674. /// \par Complexity
  2675. /// `O(N)`.
  2676. /// \ingroup query
  2677. template <META_TYPE_CONSTRAINT(list_like) L, typename T>
  2678. using in = not_<empty<find<L, T>>>;
  2679. namespace lazy
  2680. {
  2681. /// \sa 'meta::in'
  2682. /// \ingroup lazy_query
  2683. template <typename L, typename T>
  2684. using in = defer<in, L, T>;
  2685. } // namespace lazy
  2686. ///////////////////////////////////////////////////////////////////////////////////////////
  2687. // inherit
  2688. /// \cond
  2689. namespace detail
  2690. {
  2691. template <typename L>
  2692. struct inherit_
  2693. {
  2694. };
  2695. template <typename... L>
  2696. struct inherit_<list<L...>> : L...
  2697. {
  2698. using type = inherit_;
  2699. };
  2700. } // namespace detail
  2701. /// \endcond
  2702. /// A type that inherits from all the types in the list
  2703. /// \pre The types in the list must be unique
  2704. /// \pre All the types in the list must be non-final class types
  2705. /// \ingroup datatype
  2706. template <META_TYPE_CONSTRAINT(list_like) L>
  2707. using inherit = meta::_t<detail::inherit_<L>>;
  2708. namespace lazy
  2709. {
  2710. /// \sa 'meta::inherit'
  2711. /// \ingroup lazy_datatype
  2712. template <typename L>
  2713. using inherit = defer<inherit, L>;
  2714. } // namespace lazy
  2715. ///////////////////////////////////////////////////////////////////////////////////////////
  2716. // unique
  2717. /// \cond
  2718. namespace detail
  2719. {
  2720. template <typename Set, typename T>
  2721. struct in_
  2722. {
  2723. };
  2724. template <typename... Set, typename T>
  2725. struct in_<list<Set...>, T> : bool_<META_IS_BASE_OF(id<T>, inherit<list<id<Set>...>>)>
  2726. {
  2727. };
  2728. template <typename Set, typename T>
  2729. struct insert_back_
  2730. {
  2731. };
  2732. template <typename... Set, typename T>
  2733. struct insert_back_<list<Set...>, T>
  2734. {
  2735. using type = if_<in_<list<Set...>, T>, list<Set...>, list<Set..., T>>;
  2736. };
  2737. } // namespace detail
  2738. /// \endcond
  2739. /// Return a new \c meta::list where all duplicate elements have been removed.
  2740. /// \par Complexity
  2741. /// `O(N^2)`.
  2742. /// \ingroup transformation
  2743. template <META_TYPE_CONSTRAINT(list_like) L>
  2744. using unique = fold<L, list<>, quote_trait<detail::insert_back_>>;
  2745. namespace lazy
  2746. {
  2747. /// \sa 'meta::unique'
  2748. /// \ingroup lazy_transformation
  2749. template <typename L>
  2750. using unique = defer<unique, L>;
  2751. } // namespace lazy
  2752. ///////////////////////////////////////////////////////////////////////////////////////////
  2753. // partition
  2754. /// \cond
  2755. namespace detail
  2756. {
  2757. template <typename Fn>
  2758. struct partition_
  2759. {
  2760. #ifdef META_CONCEPT
  2761. template <typename, typename>
  2762. #else
  2763. template <typename, typename, typename = void>
  2764. #endif
  2765. struct impl
  2766. {
  2767. };
  2768. template <typename... Yes, typename... No, typename A>
  2769. #ifdef META_CONCEPT
  2770. requires integral<invoke<Fn, A>>
  2771. struct impl<pair<list<Yes...>, list<No...>>, A>
  2772. #else
  2773. struct impl<pair<list<Yes...>, list<No...>>, A,
  2774. void_<bool_<invoke<Fn, A>::type::value>>>
  2775. #endif
  2776. {
  2777. using type = if_<meta::invoke<Fn, A>, pair<list<Yes..., A>, list<No...>>,
  2778. pair<list<Yes...>, list<No..., A>>>;
  2779. };
  2780. template <typename State, typename A>
  2781. using invoke = _t<impl<State, A>>;
  2782. };
  2783. } // namespace detail
  2784. /// \endcond
  2785. /// Returns a pair of lists, where the elements of \p L that satisfy the
  2786. /// invocable \p Fn such that `invoke<Fn,A>::%value` is \c true are present in the
  2787. /// first list and the rest are in the second.
  2788. /// \par Complexity
  2789. /// `O(N)`.
  2790. /// \ingroup transformation
  2791. template <META_TYPE_CONSTRAINT(list_like) L, META_TYPE_CONSTRAINT(invocable) Fn>
  2792. using partition = fold<L, pair<list<>, list<>>, detail::partition_<Fn>>;
  2793. namespace lazy
  2794. {
  2795. /// \sa 'meta::partition'
  2796. /// \ingroup lazy_transformation
  2797. template <typename L, typename Fn>
  2798. using partition = defer<partition, L, Fn>;
  2799. } // namespace lazy
  2800. ///////////////////////////////////////////////////////////////////////////////////////////
  2801. // sort
  2802. /// \cond
  2803. namespace detail
  2804. {
  2805. template <META_TYPE_CONSTRAINT(invocable) Fn, typename A, typename B, typename... Ts>
  2806. using part_ = partition<list<B, Ts...>, bind_back<Fn, A>>;
  2807. #ifdef META_CONCEPT
  2808. template <typename L, typename Fn>
  2809. requires list_like<L> && invocable<Fn>
  2810. #else
  2811. template <typename, typename, typename = void>
  2812. #endif
  2813. struct sort_
  2814. {
  2815. };
  2816. template <typename Fn>
  2817. struct sort_<list<>, Fn>
  2818. {
  2819. using type = list<>;
  2820. };
  2821. template <typename A, typename Fn>
  2822. struct sort_<list<A>, Fn>
  2823. {
  2824. using type = list<A>;
  2825. };
  2826. template <typename A, typename B, typename... Ts, typename Fn>
  2827. #ifdef META_CONCEPT
  2828. requires trait<sort_<first<part_<Fn, A, B, Ts...>>, Fn>> &&
  2829. trait<sort_<second<part_<Fn, A, B, Ts...>>, Fn>>
  2830. struct sort_<list<A, B, Ts...>, Fn>
  2831. #else
  2832. struct sort_<
  2833. list<A, B, Ts...>, Fn,
  2834. void_<_t<sort_<first<part_<Fn, A, B, Ts...>>, Fn>>>>
  2835. #endif
  2836. {
  2837. using P = part_<Fn, A, B, Ts...>;
  2838. using type = concat<_t<sort_<first<P>, Fn>>, list<A>, _t<sort_<second<P>, Fn>>>;
  2839. };
  2840. } // namespace detail
  2841. /// \endcond
  2842. // clang-format off
  2843. /// Return a new \c meta::list that is sorted according to invocable predicate \p Fn.
  2844. /// \par Complexity
  2845. /// Expected: `O(N log N)`
  2846. /// Worst case: `O(N^2)`.
  2847. /// \code
  2848. /// using L0 = list<char[5], char[3], char[2], char[6], char[1], char[5], char[10]>;
  2849. /// using L1 = meta::sort<L0, lambda<_a, _b, lazy::less<lazy::sizeof_<_a>, lazy::sizeof_<_b>>>>;
  2850. /// static_assert(std::is_same_v<L1, list<char[1], char[2], char[3], char[5], char[5], char[6], char[10]>>, "");
  2851. /// \endcode
  2852. /// \ingroup transformation
  2853. // clang-format on
  2854. template <META_TYPE_CONSTRAINT(list_like) L, META_TYPE_CONSTRAINT(invocable) Fn>
  2855. using sort = _t<detail::sort_<L, Fn>>;
  2856. namespace lazy
  2857. {
  2858. /// \sa 'meta::sort'
  2859. /// \ingroup lazy_transformation
  2860. template <typename L, typename Fn>
  2861. using sort = defer<sort, L, Fn>;
  2862. } // namespace lazy
  2863. ////////////////////////////////////////////////////////////////////////////
  2864. // lambda_
  2865. /// \cond
  2866. namespace detail
  2867. {
  2868. template <typename T, int = 0>
  2869. struct protect_;
  2870. template <typename, int = 0>
  2871. struct vararg_;
  2872. template <typename T, int = 0>
  2873. struct is_valid_;
  2874. // Returns which branch to evaluate
  2875. template <typename If, typename... Ts>
  2876. #ifdef META_CONCEPT
  2877. using lazy_if_ = lazy::_t<defer<_if_, If, protect_<Ts>...>>;
  2878. #else
  2879. using lazy_if_ = lazy::_t<defer<_if_, list<If, protect_<Ts>...>>>;
  2880. #endif
  2881. template <typename A, typename T, typename Fn, typename Ts>
  2882. struct subst1_
  2883. {
  2884. using type = list<list<T>>;
  2885. };
  2886. template <typename T, typename Fn, typename Ts>
  2887. struct subst1_<Fn, T, Fn, Ts>
  2888. {
  2889. using type = list<>;
  2890. };
  2891. template <typename A, typename T, typename Fn, typename Ts>
  2892. struct subst1_<vararg_<A>, T, Fn, Ts>
  2893. {
  2894. using type = list<Ts>;
  2895. };
  2896. template <typename As, typename Ts>
  2897. using substitutions_ = push_back<
  2898. join<transform<
  2899. concat<As, repeat_n_c<size<Ts>{} + 2 - size<As>{}, back<As>>>,
  2900. concat<Ts, repeat_n_c<2, back<As>>>,
  2901. bind_back<quote_trait<subst1_>, back<As>, drop_c<Ts, size<As>{} - 2>>>>,
  2902. list<back<As>>>;
  2903. #if 0//def META_CONCEPT
  2904. template <list_like As, list_like Ts>
  2905. requires (_v<size<Ts>> + 2 >= _v<size<As>>)
  2906. using substitutions = substitutions_<As, Ts>;
  2907. #else // ^^^ concepts / no concepts vvv
  2908. template <typename As, typename Ts>
  2909. using substitutions =
  2910. #ifdef META_WORKAROUND_MSVC_702792
  2911. invoke<if_c<(size<Ts>::value + 2 >= size<As>::value), quote<substitutions_>>, As,
  2912. Ts>;
  2913. #else // ^^^ workaround ^^^ / vvv no workaround vvv
  2914. invoke<if_c<(size<Ts>{} + 2 >= size<As>{}), quote<substitutions_>>, As, Ts>;
  2915. #endif // META_WORKAROUND_MSVC_702792
  2916. #endif // META_CONCEPT
  2917. template <typename T>
  2918. struct is_vararg_ : std::false_type
  2919. {
  2920. };
  2921. template <typename T>
  2922. struct is_vararg_<vararg_<T>> : std::true_type
  2923. {
  2924. };
  2925. template <META_TYPE_CONSTRAINT(list_like) Tags>
  2926. using is_variadic_ = is_vararg_<at<push_front<Tags, void>, dec<size<Tags>>>>;
  2927. template <META_TYPE_CONSTRAINT(list_like) Tags, bool IsVariadic = is_variadic_<Tags>::value>
  2928. struct lambda_;
  2929. // Non-variadic lambda implementation
  2930. template <typename... As>
  2931. struct lambda_<list<As...>, false>
  2932. {
  2933. private:
  2934. static constexpr std::size_t arity = sizeof...(As) - 1;
  2935. using Tags = list<As...>; // Includes the lambda body as the last arg!
  2936. using Fn = back<Tags>;
  2937. template <typename T, META_TYPE_CONSTRAINT(list_like) Args>
  2938. struct impl;
  2939. template <typename T, META_TYPE_CONSTRAINT(list_like) Args>
  2940. using lazy_impl_ = lazy::_t<defer<impl, T, protect_<Args>>>;
  2941. #if 0//def META_CONCEPT
  2942. template <typename, list_like>
  2943. #else
  2944. template <typename, typename, typename = void>
  2945. #endif
  2946. struct subst_
  2947. {
  2948. };
  2949. template <template <typename...> class C, typename... Ts, typename Args>
  2950. #if 0//def META_CONCEPT
  2951. requires valid<C, _t<impl<Ts, Args>>...> struct subst_<defer<C, Ts...>, Args>
  2952. #else
  2953. struct subst_<defer<C, Ts...>, Args, void_<C<_t<impl<Ts, Args>>...>>>
  2954. #endif
  2955. {
  2956. using type = C<_t<impl<Ts, Args>>...>;
  2957. };
  2958. template <typename T, template <T...> class C, T... Is, typename Args>
  2959. #if 0//def META_CONCEPT
  2960. requires valid_i<T, C, Is...> struct subst_<defer_i<T, C, Is...>, Args>
  2961. #else
  2962. struct subst_<defer_i<T, C, Is...>, Args, void_<C<Is...>>>
  2963. #endif
  2964. {
  2965. using type = C<Is...>;
  2966. };
  2967. template <typename T, META_TYPE_CONSTRAINT(list_like) Args>
  2968. struct impl : if_c<(reverse_find_index<Tags, T>() != npos()),
  2969. lazy::at<Args, reverse_find_index<Tags, T>>, id<T>>
  2970. {
  2971. };
  2972. template <typename T, typename Args>
  2973. struct impl<protect_<T>, Args>
  2974. {
  2975. using type = T;
  2976. };
  2977. template <typename T, typename Args>
  2978. struct impl<is_valid_<T>, Args>
  2979. {
  2980. using type = is_trait<impl<T, Args>>;
  2981. };
  2982. template <typename If, typename... Ts, typename Args>
  2983. struct impl<defer<if_, If, Ts...>, Args> // Short-circuit if_
  2984. : impl<lazy_impl_<lazy_if_<If, Ts...>, Args>, Args>
  2985. {
  2986. };
  2987. template <typename B, typename... Bs, typename Args>
  2988. struct impl<defer<and_, B, Bs...>, Args> // Short-circuit and_
  2989. : impl<lazy_impl_<lazy_if_<B, lazy::and_<Bs...>, protect_<std::false_type>>, Args>,
  2990. Args>
  2991. {
  2992. };
  2993. template <typename B, typename... Bs, typename Args>
  2994. struct impl<defer<or_, B, Bs...>, Args> // Short-circuit or_
  2995. : impl<lazy_impl_<lazy_if_<B, protect_<std::true_type>, lazy::or_<Bs...>>, Args>,
  2996. Args>
  2997. {
  2998. };
  2999. template <template <typename...> class C, typename... Ts, typename Args>
  3000. struct impl<defer<C, Ts...>, Args> : subst_<defer<C, Ts...>, Args>
  3001. {
  3002. };
  3003. template <typename T, template <T...> class C, T... Is, typename Args>
  3004. struct impl<defer_i<T, C, Is...>, Args> : subst_<defer_i<T, C, Is...>, Args>
  3005. {
  3006. };
  3007. template <template <typename...> class C, typename... Ts, typename Args>
  3008. struct impl<C<Ts...>, Args> : subst_<defer<C, Ts...>, Args>
  3009. {
  3010. };
  3011. template <typename... Ts, typename Args>
  3012. struct impl<lambda_<list<Ts...>, false>, Args>
  3013. {
  3014. using type = compose<uncurry<lambda_<list<As..., Ts...>, false>>,
  3015. curry<bind_front<quote<concat>, Args>>>;
  3016. };
  3017. template <typename... Bs, typename Args>
  3018. struct impl<lambda_<list<Bs...>, true>, Args>
  3019. {
  3020. using type = compose<typename lambda_<list<As..., Bs...>, true>::thunk,
  3021. bind_front<quote<concat>, transform<Args, quote<list>>>,
  3022. curry<bind_front<quote<substitutions>, list<Bs...>>>>;
  3023. };
  3024. public:
  3025. template <typename... Ts>
  3026. #ifdef META_CONCEPT
  3027. requires (sizeof...(Ts) == arity) using invoke = _t<impl<Fn, list<Ts..., Fn>>>;
  3028. #else
  3029. using invoke = _t<if_c<sizeof...(Ts) == arity, impl<Fn, list<Ts..., Fn>>>>;
  3030. #endif
  3031. };
  3032. // Lambda with variadic placeholder (broken out due to less efficient compile-time
  3033. // resource usage)
  3034. template <typename... As>
  3035. struct lambda_<list<As...>, true>
  3036. {
  3037. private:
  3038. template <META_TYPE_CONSTRAINT(list_like) T, bool IsVar>
  3039. friend struct lambda_;
  3040. using Tags = list<As...>; // Includes the lambda body as the last arg!
  3041. template <typename T, META_TYPE_CONSTRAINT(list_like) Args>
  3042. struct impl;
  3043. template <META_TYPE_CONSTRAINT(list_like) Args>
  3044. using eval_impl_ = bind_back<quote_trait<impl>, Args>;
  3045. template <typename T, META_TYPE_CONSTRAINT(list_like) Args>
  3046. using lazy_impl_ = lazy::_t<defer<impl, T, protect_<Args>>>;
  3047. template <template <typename...> class C, META_TYPE_CONSTRAINT(list_like) Args,
  3048. META_TYPE_CONSTRAINT(list_like) Ts>
  3049. using try_subst_ = apply<quote<C>, join<transform<Ts, eval_impl_<Args>>>>;
  3050. #if 0//def META_CONCEPT
  3051. template <typename, list_like>
  3052. #else
  3053. template <typename, typename, typename = void>
  3054. #endif
  3055. struct subst_
  3056. {
  3057. };
  3058. template <template <typename...> class C, typename... Ts, typename Args>
  3059. #if 0//def META_CONCEPT
  3060. requires is_true<try_subst_<C, Args, list<Ts...>>> struct subst_<defer<C, Ts...>, Args>
  3061. #else
  3062. struct subst_<defer<C, Ts...>, Args, void_<try_subst_<C, Args, list<Ts...>>>>
  3063. #endif
  3064. {
  3065. using type = list<try_subst_<C, Args, list<Ts...>>>;
  3066. };
  3067. template <typename T, template <T...> class C, T... Is, typename Args>
  3068. #if 0//def META_CONCEPT
  3069. requires valid_i<T, C, Is...> struct subst_<defer_i<T, C, Is...>, Args>
  3070. #else
  3071. struct subst_<defer_i<T, C, Is...>, Args, void_<C<Is...>>>
  3072. #endif
  3073. {
  3074. using type = list<C<Is...>>;
  3075. };
  3076. template <typename T, META_TYPE_CONSTRAINT(list_like) Args>
  3077. struct impl : if_c<(reverse_find_index<Tags, T>() != npos()),
  3078. lazy::at<Args, reverse_find_index<Tags, T>>, id<list<T>>>
  3079. {
  3080. };
  3081. template <typename T, typename Args>
  3082. struct impl<protect_<T>, Args>
  3083. {
  3084. using type = list<T>;
  3085. };
  3086. template <typename T, typename Args>
  3087. struct impl<is_valid_<T>, Args>
  3088. {
  3089. using type = list<is_trait<impl<T, Args>>>;
  3090. };
  3091. template <typename If, typename... Ts, typename Args>
  3092. struct impl<defer<if_, If, Ts...>, Args> // Short-circuit if_
  3093. : impl<lazy_impl_<lazy_if_<If, Ts...>, Args>, Args>
  3094. {
  3095. };
  3096. template <typename B, typename... Bs, typename Args>
  3097. struct impl<defer<and_, B, Bs...>, Args> // Short-circuit and_
  3098. : impl<lazy_impl_<lazy_if_<B, lazy::and_<Bs...>, protect_<std::false_type>>, Args>,
  3099. Args>
  3100. {
  3101. };
  3102. template <typename B, typename... Bs, typename Args>
  3103. struct impl<defer<or_, B, Bs...>, Args> // Short-circuit or_
  3104. : impl<lazy_impl_<lazy_if_<B, protect_<std::true_type>, lazy::or_<Bs...>>, Args>,
  3105. Args>
  3106. {
  3107. };
  3108. template <template <typename...> class C, typename... Ts, typename Args>
  3109. struct impl<defer<C, Ts...>, Args> : subst_<defer<C, Ts...>, Args>
  3110. {
  3111. };
  3112. template <typename T, template <T...> class C, T... Is, typename Args>
  3113. struct impl<defer_i<T, C, Is...>, Args> : subst_<defer_i<T, C, Is...>, Args>
  3114. {
  3115. };
  3116. template <template <typename...> class C, typename... Ts, typename Args>
  3117. struct impl<C<Ts...>, Args> : subst_<defer<C, Ts...>, Args>
  3118. {
  3119. };
  3120. template <typename... Bs, bool IsVar, typename Args>
  3121. struct impl<lambda_<list<Bs...>, IsVar>, Args>
  3122. {
  3123. using type =
  3124. list<compose<typename lambda_<list<As..., Bs...>, true>::thunk,
  3125. bind_front<quote<concat>, Args>,
  3126. curry<bind_front<quote<substitutions>, list<Bs...>>>>>;
  3127. };
  3128. struct thunk
  3129. {
  3130. template <typename S, typename R = _t<impl<back<Tags>, S>>>
  3131. #ifdef META_CONCEPT
  3132. requires (_v<size<R>> == 1) using invoke = front<R>;
  3133. #else
  3134. using invoke = if_c<size<R>{} == 1, front<R>>;
  3135. #endif
  3136. };
  3137. public:
  3138. template <typename... Ts>
  3139. using invoke = invoke<thunk, substitutions<Tags, list<Ts...>>>;
  3140. };
  3141. } // namespace detail
  3142. /// \endcond
  3143. ///////////////////////////////////////////////////////////////////////////////////////////
  3144. // lambda
  3145. /// For creating anonymous Invocables.
  3146. /// \code
  3147. /// using L = lambda<_a, _b, std::pair<_b, std::pair<_a, _a>>>;
  3148. /// using P = invoke<L, int, short>;
  3149. /// static_assert(std::is_same_v<P, std::pair<short, std::pair<int, int>>>, "");
  3150. /// \endcode
  3151. /// \ingroup trait
  3152. template <typename... Ts>
  3153. #ifdef META_CONCEPT
  3154. requires (sizeof...(Ts) > 0) using lambda = detail::lambda_<list<Ts...>>;
  3155. #else
  3156. using lambda = if_c<(sizeof...(Ts) > 0), detail::lambda_<list<Ts...>>>;
  3157. #endif
  3158. ///////////////////////////////////////////////////////////////////////////////////////////
  3159. // is_valid
  3160. /// For testing whether a deferred computation will succeed in a \c let or a \c lambda.
  3161. /// \ingroup trait
  3162. template <typename T>
  3163. using is_valid = detail::is_valid_<T>;
  3164. ///////////////////////////////////////////////////////////////////////////////////////////
  3165. // vararg
  3166. /// For defining variadic placeholders.
  3167. template <typename T>
  3168. using vararg = detail::vararg_<T>;
  3169. ///////////////////////////////////////////////////////////////////////////////////////////
  3170. // protect
  3171. /// For preventing the evaluation of a nested `defer`ed computation in a \c let or
  3172. /// \c lambda expression.
  3173. template <typename T>
  3174. using protect = detail::protect_<T>;
  3175. ///////////////////////////////////////////////////////////////////////////////////////////
  3176. // var
  3177. /// For use when defining local variables in \c meta::let expressions
  3178. /// \sa `meta::let`
  3179. template <typename Tag, typename Value>
  3180. struct var;
  3181. /// \cond
  3182. namespace detail
  3183. {
  3184. template <typename...>
  3185. struct let_
  3186. {
  3187. };
  3188. template <typename Fn>
  3189. struct let_<Fn>
  3190. {
  3191. using type = lazy::invoke<lambda<Fn>>;
  3192. };
  3193. template <typename Tag, typename Value, typename... Rest>
  3194. struct let_<var<Tag, Value>, Rest...>
  3195. {
  3196. using type = lazy::invoke<lambda<Tag, _t<let_<Rest...>>>, Value>;
  3197. };
  3198. } // namespace detail
  3199. /// \endcond
  3200. /// A lexically scoped expression with local variables.
  3201. ///
  3202. /// \code
  3203. /// template <typename T, typename L>
  3204. /// using find_index_ = let<
  3205. /// var<_a, L>,
  3206. /// var<_b, lazy::find<_a, T>>,
  3207. /// lazy::if_<
  3208. /// std::is_same<_b, list<>>,
  3209. /// meta::npos,
  3210. /// lazy::minus<lazy::size<_a>, lazy::size<_b>>>>;
  3211. /// static_assert(find_index_<int, list<short, int, float>>{} == 1, "");
  3212. /// static_assert(find_index_<double, list<short, int, float>>{} == meta::npos{}, "");
  3213. /// \endcode
  3214. /// \ingroup trait
  3215. template <typename... As>
  3216. using let = _t<_t<detail::let_<As...>>>;
  3217. namespace lazy
  3218. {
  3219. /// \sa `meta::let`
  3220. /// \ingroup lazy_trait
  3221. template <typename... As>
  3222. using let = defer<let, As...>;
  3223. } // namespace lazy
  3224. // Some argument placeholders for use in \c lambda expressions.
  3225. /// \ingroup trait
  3226. inline namespace placeholders
  3227. {
  3228. // regular placeholders:
  3229. struct _a;
  3230. struct _b;
  3231. struct _c;
  3232. struct _d;
  3233. struct _e;
  3234. struct _f;
  3235. struct _g;
  3236. struct _h;
  3237. struct _i;
  3238. // variadic placeholders:
  3239. using _args = vararg<void>;
  3240. using _args_a = vararg<_a>;
  3241. using _args_b = vararg<_b>;
  3242. using _args_c = vararg<_c>;
  3243. } // namespace placeholders
  3244. ///////////////////////////////////////////////////////////////////////////////////////////
  3245. // cartesian_product
  3246. /// \cond
  3247. namespace detail
  3248. {
  3249. template <typename M2, typename M>
  3250. struct cartesian_product_fn
  3251. {
  3252. template <typename X>
  3253. struct lambda0
  3254. {
  3255. template <typename Xs>
  3256. using lambda1 = list<push_front<Xs, X>>;
  3257. using type = join<transform<M2, quote<lambda1>>>;
  3258. };
  3259. using type = join<transform<M, quote_trait<lambda0>>>;
  3260. };
  3261. } // namespace detail
  3262. /// \endcond
  3263. /// Given a list of lists \p ListOfLists, return a new list of lists that is the Cartesian
  3264. /// Product. Like the `sequence` function from the Haskell Prelude.
  3265. /// \par Complexity
  3266. /// `O(N * M)`, where `N` is the size of the outer list, and
  3267. /// `M` is the size of the inner lists.
  3268. /// \ingroup transformation
  3269. template <META_TYPE_CONSTRAINT(list_like) ListOfLists>
  3270. using cartesian_product =
  3271. reverse_fold<ListOfLists, list<list<>>, quote_trait<detail::cartesian_product_fn>>;
  3272. namespace lazy
  3273. {
  3274. /// \sa 'meta::cartesian_product'
  3275. /// \ingroup lazy_transformation
  3276. template <typename ListOfLists>
  3277. using cartesian_product = defer<cartesian_product, ListOfLists>;
  3278. } // namespace lazy
  3279. /// \cond
  3280. ///////////////////////////////////////////////////////////////////////////////////////////
  3281. // add_const_if
  3282. namespace detail
  3283. {
  3284. template <bool>
  3285. struct add_const_if
  3286. {
  3287. template <typename T>
  3288. using invoke = T const;
  3289. };
  3290. template <>
  3291. struct add_const_if<false>
  3292. {
  3293. template <typename T>
  3294. using invoke = T;
  3295. };
  3296. } // namespace detail
  3297. template <bool If>
  3298. using add_const_if_c = detail::add_const_if<If>;
  3299. template <META_TYPE_CONSTRAINT(integral) If>
  3300. using add_const_if = add_const_if_c<If::type::value>;
  3301. /// \endcond
  3302. /// \cond
  3303. ///////////////////////////////////////////////////////////////////////////////////////////
  3304. // const_if
  3305. template <bool If, typename T>
  3306. using const_if_c = typename add_const_if_c<If>::template invoke<T>;
  3307. template <typename If, typename T>
  3308. using const_if = typename add_const_if<If>::template invoke<T>;
  3309. /// \endcond
  3310. /// \cond
  3311. namespace detail
  3312. {
  3313. template <typename State, typename Ch>
  3314. using atoi_ = if_c<(Ch::value >= '0' && Ch::value <= '9'),
  3315. std::integral_constant<typename State::value_type,
  3316. State::value * 10 + (Ch::value - '0')>>;
  3317. }
  3318. /// \endcond
  3319. inline namespace literals
  3320. {
  3321. /// A user-defined literal that generates objects of type \c meta::size_t.
  3322. /// \ingroup integral
  3323. template <char... Chs>
  3324. constexpr fold<list<char_<Chs>...>, meta::size_t<0>, quote<detail::atoi_>>
  3325. operator"" _z()
  3326. {
  3327. return {};
  3328. }
  3329. } // namespace literals
  3330. } // namespace meta
  3331. /// \cond
  3332. // Non-portable forward declarations of standard containers
  3333. #ifndef META_NO_STD_FORWARD_DECLARATIONS
  3334. #if defined(__apple_build_version__) || (defined(__clang__) && __clang_major__ < 6)
  3335. META_BEGIN_NAMESPACE_STD
  3336. META_BEGIN_NAMESPACE_VERSION
  3337. template <class>
  3338. class META_TEMPLATE_VIS allocator;
  3339. template <class, class>
  3340. struct META_TEMPLATE_VIS pair;
  3341. template <class>
  3342. struct META_TEMPLATE_VIS hash;
  3343. template <class>
  3344. struct META_TEMPLATE_VIS less;
  3345. template <class>
  3346. struct META_TEMPLATE_VIS equal_to;
  3347. template <class>
  3348. struct META_TEMPLATE_VIS char_traits;
  3349. #if defined(_GLIBCXX_USE_CXX11_ABI) && _GLIBCXX_USE_CXX11_ABI
  3350. inline namespace __cxx11 {
  3351. #endif
  3352. template <class, class, class>
  3353. class META_TEMPLATE_VIS basic_string;
  3354. #if defined(_GLIBCXX_USE_CXX11_ABI) && _GLIBCXX_USE_CXX11_ABI
  3355. }
  3356. #endif
  3357. META_END_NAMESPACE_VERSION
  3358. META_BEGIN_NAMESPACE_CONTAINER
  3359. #if defined(__GLIBCXX__)
  3360. inline namespace __cxx11 {
  3361. #endif
  3362. template <class, class>
  3363. class META_TEMPLATE_VIS list;
  3364. #if defined(__GLIBCXX__)
  3365. }
  3366. #endif
  3367. template <class, class>
  3368. class META_TEMPLATE_VIS forward_list;
  3369. template <class, class>
  3370. class META_TEMPLATE_VIS vector;
  3371. template <class, class>
  3372. class META_TEMPLATE_VIS deque;
  3373. template <class, class, class, class>
  3374. class META_TEMPLATE_VIS map;
  3375. template <class, class, class, class>
  3376. class META_TEMPLATE_VIS multimap;
  3377. template <class, class, class>
  3378. class META_TEMPLATE_VIS set;
  3379. template <class, class, class>
  3380. class META_TEMPLATE_VIS multiset;
  3381. template <class, class, class, class, class>
  3382. class META_TEMPLATE_VIS unordered_map;
  3383. template <class, class, class, class, class>
  3384. class META_TEMPLATE_VIS unordered_multimap;
  3385. template <class, class, class, class>
  3386. class META_TEMPLATE_VIS unordered_set;
  3387. template <class, class, class, class>
  3388. class META_TEMPLATE_VIS unordered_multiset;
  3389. template <class, class>
  3390. class META_TEMPLATE_VIS queue;
  3391. template <class, class, class>
  3392. class META_TEMPLATE_VIS priority_queue;
  3393. template <class, class>
  3394. class META_TEMPLATE_VIS stack;
  3395. META_END_NAMESPACE_CONTAINER
  3396. META_END_NAMESPACE_STD
  3397. namespace meta
  3398. {
  3399. namespace detail
  3400. {
  3401. template <typename T, typename A = std::allocator<T>>
  3402. using std_list = std::list<T, A>;
  3403. template <typename T, typename A = std::allocator<T>>
  3404. using std_forward_list = std::forward_list<T, A>;
  3405. template <typename T, typename A = std::allocator<T>>
  3406. using std_vector = std::vector<T, A>;
  3407. template <typename T, typename A = std::allocator<T>>
  3408. using std_deque = std::deque<T, A>;
  3409. template <typename T, typename C = std::char_traits<T>, typename A = std::allocator<T>>
  3410. using std_basic_string = std::basic_string<T, C, A>;
  3411. template <typename K, typename V, typename C = std::less<K>,
  3412. typename A = std::allocator<std::pair<K const, V>>>
  3413. using std_map = std::map<K, V, C, A>;
  3414. template <typename K, typename V, typename C = std::less<K>,
  3415. typename A = std::allocator<std::pair<K const, V>>>
  3416. using std_multimap = std::multimap<K, V, C, A>;
  3417. template <typename K, typename C = std::less<K>, typename A = std::allocator<K>>
  3418. using std_set = std::set<K, C, A>;
  3419. template <typename K, typename C = std::less<K>, typename A = std::allocator<K>>
  3420. using std_multiset = std::multiset<K, C, A>;
  3421. template <typename K, typename V, typename H = std::hash<K>,
  3422. typename C = std::equal_to<K>,
  3423. typename A = std::allocator<std::pair<K const, V>>>
  3424. using std_unordered_map = std::unordered_map<K, V, H, C, A>;
  3425. template <typename K, typename V, typename H = std::hash<K>,
  3426. typename C = std::equal_to<K>,
  3427. typename A = std::allocator<std::pair<K const, V>>>
  3428. using std_unordered_multimap = std::unordered_multimap<K, V, H, C, A>;
  3429. template <typename K, typename H = std::hash<K>, typename C = std::equal_to<K>,
  3430. typename A = std::allocator<K>>
  3431. using std_unordered_set = std::unordered_set<K, H, C, A>;
  3432. template <typename K, typename H = std::hash<K>, typename C = std::equal_to<K>,
  3433. typename A = std::allocator<K>>
  3434. using std_unordered_multiset = std::unordered_multiset<K, H, C, A>;
  3435. template <typename T, typename C = std_deque<T>>
  3436. using std_queue = std::queue<T, C>;
  3437. template <typename T, typename C = std_vector<T>,
  3438. class D = std::less<typename C::value_type>>
  3439. using std_priority_queue = std::priority_queue<T, C, D>;
  3440. template <typename T, typename C = std_deque<T>>
  3441. using std_stack = std::stack<T, C>;
  3442. } // namespace detail
  3443. template <>
  3444. struct quote<::std::list> : quote<detail::std_list>
  3445. {
  3446. };
  3447. template <>
  3448. struct quote<::std::deque> : quote<detail::std_deque>
  3449. {
  3450. };
  3451. template <>
  3452. struct quote<::std::forward_list> : quote<detail::std_forward_list>
  3453. {
  3454. };
  3455. template <>
  3456. struct quote<::std::vector> : quote<detail::std_vector>
  3457. {
  3458. };
  3459. template <>
  3460. struct quote<::std::basic_string> : quote<detail::std_basic_string>
  3461. {
  3462. };
  3463. template <>
  3464. struct quote<::std::map> : quote<detail::std_map>
  3465. {
  3466. };
  3467. template <>
  3468. struct quote<::std::multimap> : quote<detail::std_multimap>
  3469. {
  3470. };
  3471. template <>
  3472. struct quote<::std::set> : quote<detail::std_set>
  3473. {
  3474. };
  3475. template <>
  3476. struct quote<::std::multiset> : quote<detail::std_multiset>
  3477. {
  3478. };
  3479. template <>
  3480. struct quote<::std::unordered_map> : quote<detail::std_unordered_map>
  3481. {
  3482. };
  3483. template <>
  3484. struct quote<::std::unordered_multimap> : quote<detail::std_unordered_multimap>
  3485. {
  3486. };
  3487. template <>
  3488. struct quote<::std::unordered_set> : quote<detail::std_unordered_set>
  3489. {
  3490. };
  3491. template <>
  3492. struct quote<::std::unordered_multiset> : quote<detail::std_unordered_multiset>
  3493. {
  3494. };
  3495. template <>
  3496. struct quote<::std::queue> : quote<detail::std_queue>
  3497. {
  3498. };
  3499. template <>
  3500. struct quote<::std::priority_queue> : quote<detail::std_priority_queue>
  3501. {
  3502. };
  3503. template <>
  3504. struct quote<::std::stack> : quote<detail::std_stack>
  3505. {
  3506. };
  3507. } // namespace meta
  3508. #endif
  3509. #endif
  3510. /// \endcond
  3511. #ifdef __clang__
  3512. #pragma GCC diagnostic pop
  3513. #endif
  3514. #endif