diff --git a/README_zh.md b/README_zh.md index dbeff436..a2f7e4a6 100644 --- a/README_zh.md +++ b/README_zh.md @@ -14,6 +14,7 @@ * [特性](#特性) * [Demo](#demo) +* [模型列表](#模型列表) * [环境要求](#环境要求) * [编译](#编译) * [安装](#安装) @@ -54,6 +55,53 @@ StackFlow 语音助手的主要工作模式: - [StackFlow yolo 视觉检测](https://github.com/Abandon-ht/ModuleLLM_Development_Guide/tree/dev/ESP32/cpp) - [StackFlow VLM 图片描述](https://github.com/Abandon-ht/ModuleLLM_Development_Guide/tree/dev/ESP32/cpp) +## 模型列表 +| 模型名 | 模型类型 | 模型大小 | 模型能力 | 模型配置文件 | 计算单元 | +| :----: | :----: | :----: | :----: | :----: | :----: | +| [silero-vad](https://github.com/snakers4/silero-vad) | VAD | 3.3M | 语音活动检测 | [mode_silero-vad.json](projects/llm_framework/main_vad/mode_silero-vad.json) | CPU | +| [sherpa-onnx-kws-zipformer-gigaspeech-3.3M-2024-01-01](https://github.com/k2-fsa/sherpa-onnx/releases/download/kws-models/sherpa-onnx-kws-zipformer-gigaspeech-3.3M-2024-01-01.tar.bz2) | KWS | 6.4M | 关键词识别 | [mode_sherpa-onnx-kws-zipformer-gigaspeech-3.3M-2024-01-01.json](projects/llm_framework/main_kws/mode_sherpa-onnx-kws-zipformer-gigaspeech-3.3M-2024-01-01.json) | CPU | +| [sherpa-onnx-kws-zipformer-wenetspeech-3.3M-2024-01-01](https://github.com/k2-fsa/sherpa-onnx/releases/download/kws-models/sherpa-onnx-kws-zipformer-wenetspeech-3.3M-2024-01-01.tar.bz2) | KWS | 5.7M | 关键词识别 | [mode_sherpa-onnx-kws-zipformer-wenetspeech-3.3M-2024-01-01.json](projects/llm_framework/main_kws/mode_sherpa-onnx-kws-zipformer-wenetspeech-3.3M-2024-01-01.json) | CPU | +| [sherpa-ncnn-streaming-zipformer-20M-2023-02-17](https://huggingface.co/desh2608/icefall-asr-librispeech-pruned-transducer-stateless7-streaming-small) | ASR | 40M | 语音识别 | [mode_sherpa-ncnn-streaming-zipformer-20M-2023-02-17.json](projects/llm_framework/main_asr/mode_sherpa-ncnn-streaming-zipformer-20M-2023-02-17.json) | CPU | +| [sherpa-ncnn-streaming-zipformer-zh-14M-2023-02-23](https://github.com/k2-fsa/icefall/tree/master/egs/librispeech/ASR/pruned_transducer_stateless7_streaming) | ASR | 24M | 语音识别 | [mode_sherpa-ncnn-streaming-zipformer-zh-14M-2023-02-23.json](projects/llm_framework/main_asr/mode_sherpa-ncnn-streaming-zipformer-zh-14M-2023-02-23.json) | CPU | +| [whisper-tiny](https://huggingface.co/openai/whisper-tiny) | ASR | 201M | 语音识别 | [mode_whisper-tiny.json](projects/llm_framework/main_whisper/mode_whisper-tiny.json) | NPU | +| [whisper-base](https://huggingface.co/openai/whisper-base) | ASR | 309M | 语音识别 | [mode_whisper-base.json](projects/llm_framework/main_whisper/mode_whisper-base.json) | NPU | +| [whisper-small](https://huggingface.co/openai/whisper-small) | ASR | 725M | 语音识别 | [mode_whisper-small.json](projects/llm_framework/main_whisper/mode_whisper-small.json) | NPU | +| [single-speaker-fast](https://github.com/huakunyang/SummerTTS) | TTS | 77M | 语音生成 | [mode_whisper-tiny.json](projects/llm_framework/main_tts/mode_single-speaker-fast.json) | CPU | +| [single-speaker-english-fast](https://github.com/huakunyang/SummerTTS) | TTS | 60M | 语音生成 | [mode_whisper-tiny.json](projects/llm_framework/main_tts/mode_single-speaker-english-fast.json) | CPU | +| [melotts-en-au](https://huggingface.co/myshell-ai/MeloTTS-English) | TTS | 102M | 语音生成 | [mode_melotts-en-au.json](projects/llm_framework/main_melotts/mode_melotts-en-au.json) | NPU | +| [melotts-en-br](https://huggingface.co/myshell-ai/MeloTTS-English) | TTS | 102M | 语音生成 | [mode_melotts-en-au.json](projects/llm_framework/main_melotts/mode_melotts-en-br.json) | NPU | +| [melotts-en-default](https://huggingface.co/myshell-ai/MeloTTS-English) | TTS | 102M | 语音生成 | [mode_melotts-en-india.json](projects/llm_framework/main_melotts/mode_melotts-en-default.json) | NPU | +| [melotts-en-us](https://huggingface.co/myshell-ai/MeloTTS-English) | TTS | 102M | 语音生成 | [mode_melotts-en-au.json](projects/llm_framework/main_melotts/mode_melotts-en-us.json) | NPU | +| [melotts-es-es](https://huggingface.co/myshell-ai/MeloTTS-Spanish) | TTS | 83M | 语音生成 | [mode_melotts-es-es.json](projects/llm_framework/main_melotts/mode_melotts-es-es.json) | NPU | +| [melotts-ja-jp](https://huggingface.co/myshell-ai/MeloTTS-Japanese) | TTS | 83M | 语音生成 | [mode_melotts-ja-jp.json](projects/llm_framework/main_melotts/mode_melotts-ja-jp.json) | NPU | +| [melotts-zh-cn](https://huggingface.co/myshell-ai/MeloTTS-Chinese) | TTS | 86M | 语音生成 | [mode_melotts-zh-cn.json](projects/llm_framework/main_melotts/mode_melotts-zh-cn.json) | NPU | +| [deepseek-r1-1.5B-ax630c](https://huggingface.co/deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B) | LLM | 2.0G | 文本生成 | [mode_deepseek-r1-1.5B-ax630c.json](projects/llm_framework/main_llm/models/mode_deepseek-r1-1.5B-ax630c.json) | NPU | +| [deepseek-r1-1.5B-p256-ax630c](https://huggingface.co/deepseek-ai/DeepSeek-R1-Distill-Qwen-1.5B) | LLM | 2.0G | 文本生成 | [mode_deepseek-r1-1.5B-p256-ax630c.json](projects/llm_framework/main_llm/models/mode_deepseek-r1-1.5B-p256-ax630c.json) | NPU | +| [llama3.2-1B-p256-ax630c](https://huggingface.co/meta-llama/Llama-3.2-1B) | LLM | 1.7G | 文本生成 | [mode_llama3.2-1B-p256-ax630c.json](projects/llm_framework/main_llm/models/mode_llama3.2-1B-p256-ax630c.json) | NPU | +| [llama3.2-1B-prefill-ax630c](https://huggingface.co/meta-llama/Llama-3.2-1B) | LLM | 1.7G | 文本生成 | [mode_llama3.2-1B-prefill-ax630c.json](projects/llm_framework/main_llm/models/mode_llama3.2-1B-prefill-ax630c.json) | NPU | +| [openbuddy-llama3.2-1B-ax630c](https://huggingface.co/OpenBuddy/openbuddy-llama3.2-1b-v23.1-131k) | LLM | 1.7G | 文本生成 | [mode_openbuddy-llama3.2-1B-ax630c.json](projects/llm_framework/main_llm/models/mode_openbuddy-llama3.2-1B-ax630c.json) | NPU | +| [qwen2.5-0.5B-Int4-ax630c](https://huggingface.co/Qwen/Qwen2.5-0.5B-Instruct-GPTQ-Int4) | LLM | 626M | 文本生成 | [mode_qwen2.5-0.5B-Int4-ax630c.json](projects/llm_framework/main_llm/models/mode_qwen2.5-0.5B-Int4-ax630c.json) | NPU | +| [qwen2.5-0.5B-p256-ax630c](https://huggingface.co/Qwen/Qwen2.5-0.5B-Instruct) | LLM | 760M | 文本生成 | [mode_qwen2.5-0.5B-p256-ax630c.json](projects/llm_framework/main_llm/models/mode_qwen2.5-0.5B-p256-ax630c.json) | NPU | +| [qwen2.5-0.5B-prefill-20e](https://huggingface.co/Qwen/Qwen2.5-0.5B-Instruct) | LLM | 758M | 文本生成 | [mode_qwen2.5-0.5B-prefill-20e.json](projects/llm_framework/main_llm/models/mode_qwen2.5-0.5B-prefill-20e.json) | NPU | +| [qwen2.5-1.5B-Int4-ax630c](https://huggingface.co/Qwen/Qwen2.5-1.5B-Instruct-GPTQ-Int4) | LLM | 1.5G | 文本生成 | [mode_qwen2.5-1.5B-Int4-ax630c.json](projects/llm_framework/main_llm/models/mode_qwen2.5-1.5B-Int4-ax630c.json) | NPU | +| [qwen2.5-1.5B-p256-ax630c](https://huggingface.co/Qwen/Qwen2.5-1.5B-Instruct) | LLM | 2.0G | 文本生成 | [mode_qwen2.5-1.5B-p256-ax630c.json](projects/llm_framework/main_llm/models/mode_qwen2.5-1.5B-p256-ax630c.json) | NPU | +| [qwen2.5-1.5B-ax630c](https://huggingface.co/Qwen/Qwen2.5-1.5B-Instruct) | LLM | 2.0G | 文本生成 | [mode_qwen2.5-1.5B-ax630c.json](projects/llm_framework/main_llm/models/mode_qwen2.5-1.5B-ax630c.json) | NPU | +| [qwen2.5-coder-0.5B-ax630c](https://huggingface.co/Qwen/Qwen2.5-Coder-0.5B-Instruct) | LLM | 756M | 文本生成 | [mode_qwen2.5-coder-0.5B-ax630c.json](projects/llm_framework/main_llm/models/mode_qwen2.5-coder-0.5B-ax630c.json) | NPU | +| [qwen3-0.6B-ax630c](https://huggingface.co/AXERA-TECH/InternVL2_5-1B) | LLM | 917M | 文本生成 | [mode_qwen3-0.6B-ax630c.json](projects/llm_framework/main_llm/models/mode_qwen3-0.6B-ax630c.json) | NPU | +| [mode_internvl2.5-1B-364-ax630c](https://huggingface.co/Qwen/Qwen3-0.6B) | VLM | 1.2G | 多模态文本生成 | [mode_internvl2.5-1B-364-ax630c.json](projects/llm_framework/main_vlm/models/mode_internvl2.5-1B-364-ax630c.json) | NPU | +| [smolvlm-256M-ax630c](https://huggingface.co/HuggingFaceTB/SmolVLM-256M-Instruct) | VLM | 330M | 多模态文本生成 | [mode_smolvlm-256M-ax630c.json](projects/llm_framework/main_vlm/models/mode_smolvlm-256M-ax630c.json) | NPU | +| [smolvlm-500M-ax630c](https://huggingface.co/HuggingFaceTB/SmolVLM-500M-Instruct) | VLM | 605M | 多模态文本生成 | [mode_smolvlm-256M-ax630c.json](projects/llm_framework/main_vlm/models/mode_smolvlm-500M-ax630c.json) | NPU | +| [yolo11n](https://github.com/ultralytics/ultralytics) | CV | 2.8M | 目标检测 | [mode_yolo11n.json](projects/llm_framework/main_yolo/mode_yolo11n.json) | NPU | +| [yolo11n-npu1](https://github.com/ultralytics/ultralytics) | CV | 2.8M | 目标检测 | [mode_yolo11n-npu1.json](projects/llm_framework/main_yolo/mode_yolo11n-npu1.json) | NPU | +| [yolo11n-seg](https://github.com/ultralytics/ultralytics) | CV | 3.0M | 实例分割 | [mode_yolo11n-seg.json](projects/llm_framework/main_yolo/mode_yolo11n-seg.json) | NPU | +| [yolo11n-seg-npu1](https://github.com/ultralytics/ultralytics) | CV | 3.0M | 实例分割 | [mode_yolo11n-seg-npu1.json](projects/llm_framework/main_yolo/mode_yolo11n-seg-npu1.json) | NPU | +| [yolo11n-pose](https://github.com/ultralytics/ultralytics) | CV | 3.1M | 姿态检测 | [mode_yolo11n-pose.json](projects/llm_framework/main_yolo/mode_yolo11n-pose.json) | NPU | +| [yolo11n-pose-npu1](https://github.com/ultralytics/ultralytics) | CV | 3.1M | 姿态检测 | [mode_yolo11n-pose-npu1.json](projects/llm_framework/main_yolo/mode_yolo11n-pose-npu1.json) | NPU | +| [yolo11n-hand-pose](https://github.com/ultralytics/ultralytics) | CV | 3.2M | 姿态检测 | [mode_yolo11n-hand-pose.json](projects/llm_framework/main_yolo/mode_yolo11n-hand-pose.json) | NPU | +| [yolo11n-hand-pose-npu1](https://github.com/ultralytics/ultralytics) | CV | 3.2M | 姿态检测 | [mode_yolo11n-hand-pose-npu1.json](projects/llm_framework/main_yolo/mode_yolo11n-hand-pose-npu1.json) | NPU | +| [depth-anything-ax630c](https://github.com/DepthAnything/Depth-Anything-V2) | CV | 29M | 单目深度估计 | [mode_depth-anything-ax630c.json](projects/llm_framework/main_depth_anything/mode_depth-anything-ax630c.json) | NPU | +| [depth-anything-npu1-ax630c](https://github.com/DepthAnything/Depth-Anything-V2) | CV | 29M | 单目深度估计 | [mode_depth-anything-npu1-ax630c.json](projects/llm_framework/main_depth_anything/mode_depth-anything-npu1-ax630c.json) | NPU | + ## 环境要求 ## 当前 StackFlow 的 AI 单元是建立在 AXERA 加速平台之上的,主要的芯片平台为 ax630c、ax650n。系统要求为 ubuntu。 diff --git a/doc/projects_llm_framework_doc/llm_camera_en.md b/doc/projects_llm_framework_doc/llm_camera_en.md index 25a0f05c..ddac27e0 100644 --- a/doc/projects_llm_framework_doc/llm_camera_en.md +++ b/doc/projects_llm_framework_doc/llm_camera_en.md @@ -37,6 +37,7 @@ Send JSON: - enoutput: Whether to enable user result output. If you do not need to obtain camera images, do not enable this parameter, as the video stream will increase the communication pressure on the channel. - enable_webstream: Whether to enable webstream output, webstream will listen on tcp:8989 port, and once a client connection is received, it will push jpeg images in HTTP protocol multipart/x-mixed-replace type. - rtsp: Whether to enable rtsp stream output, rtsp will establish an RTSP TCP server at rtsp://{DevIp}:8554/axstream0, and you can pull the video stream from this port using the RTSP protocol. The video stream format is 1280x720 H265. Note that this video stream is only valid on the AX630C MIPI camera, and the UVC camera cannot use RTSP. +- VinParam.bAiispEnable: Whether to enable AI-ISP, enabled by default. Set to 0 to disable, only valid when using AX630C MIPI camera. Response JSON: diff --git a/doc/projects_llm_framework_doc/llm_camera_zh.md b/doc/projects_llm_framework_doc/llm_camera_zh.md index 5675df39..4bb3cb6c 100644 --- a/doc/projects_llm_framework_doc/llm_camera_zh.md +++ b/doc/projects_llm_framework_doc/llm_camera_zh.md @@ -37,6 +37,7 @@ - enoutput:是否起用用户结果输出。如果不需要获取摄像头图片,请不要开启该参数,视频流会增加信道的通信压力。 - enable_webstream:是否启用 webstream 流输出,webstream 会监听 tcp:8989 端口,一但收到客户端连接,将会以 HTTP 协议 multipart/x-mixed-replace 类型推送 jpeg 图片。 - rtsp:是否启用 rtsp 流输出,rtsp 会建立一个 rtsp://{DevIp}:8554/axstream0 RTSP TCP 服务端,可使用RTSP 协议向该端口拉取视频流。视频流的格式为 1280x720 H265。注意,该视频流只在 AX630C MIPI 摄像头上有效,UVC 摄像头无法使用 RTSP。 +- VinParam.bAiispEnable:是否开启 AI-ISP,默认开启。关闭为 0,仅在使用 AX630C MIPI 摄像头时有效。 响应 json: diff --git a/doc/projects_llm_framework_doc/llm_cosyvoice2.md b/doc/projects_llm_framework_doc/llm_cosyvoice2.md new file mode 100644 index 00000000..19a001f7 --- /dev/null +++ b/doc/projects_llm_framework_doc/llm_cosyvoice2.md @@ -0,0 +1,223 @@ +# llm_cosy_voice + +使用 npu 加速的文字转语音单元,用于提供文字转语音服务,可使用语音克隆,用于提供多语言转语音服务。 + +## setup + +配置单元工作。 + +发送 json: + +```json +cosy_voice +{ + "request_id": "2", + "work_id": "cosy_voice", + "action": "setup", + "object": "cosy_voice.setup", + "data": { + "model": "CosyVoice2-0.5B-ax650", + "response_format": "file", + "input": "tts.utf-8", + "enoutput": false + } +} +``` + + +- request_id:参考基本数据解释。 +- work_id:配置单元时,为 `cosy_voice`。 +- action:调用的方法为 `setup`。 +- object:传输的数据类型为 `cosy_voice.setup`。 +- model:使用的模型为 `CosyVoice2-0.5B-ax650` 模型。 +- prompt_files:要克隆的音频信息文件。 +- response_format:返回结果为 `sys.pcm`, 系统音频数据,并直接发送到 llm-audio 模块进行播放。返回结果为 `file`, 生成的音频写 wav 文件,可用 `prompt_dir` 指定路径或文件名。 +- input:输入的为 `tts.utf-8`,代表的是从用户输入。 +- enoutput:是否起用用户结果输出。 + +响应 json: + +```json +{ + "created": 1761791627, + "data": "None", + "error": { + "code": 0, + "message": "" + }, + "object": "None", + "request_id": "2", + "work_id": "cosy_voice.1000" +} +``` + +- created:消息创建时间,unix 时间。 +- work_id:返回成功创建的 work_id 单元。 + +## inference + +### 流式输入 + +```json +{ + "request_id": "2", + "work_id": "cosy_voice.1000", + "action": "inference", + "object": "cosy_voice.utf-8.stream", + "data": { + "delta": "今天天气真好!", + "index": 0, + "finish": true + } +} +``` +- object:传输的数据类型为 `cosy_voice.utf-8.stream` 代表的是从用户 utf-8 的流式输入 +- delta:流式输入的分段数据 +- index:流式输入的分段索引 +- finish:流式输入是否完成的标志位 + +### 非流式输入 + +```json +{ + "request_id": "2", + "work_id": "cosy_voice.1000", + "action": "inference", + "object": "cosy_voice.utf-8", + "data": "今天天气真好!" +} +``` +- object:传输的数据类型为 `cosy_voice.utf-8` 代表的是从用户 utf-8 的非流式输入 +- data:非流式输入的数据 + +## pause + +暂停单元工作。 + +发送 json: + +```json +{ + "request_id": "5", + "work_id": "cosy_voice.1000", + "action": "pause" +} +``` + +响应 json: + +```json +{ + "created": 1761791706, + "data": "None", + "error": { + "code": 0, + "message": "" + }, + "object": "None", + "request_id": "5", + "work_id": "cosy_voice.1000" +} +``` + +error::code 为 0 表示执行成功。 + +## exit + +单元退出。 + +发送 json: + +```json +{ + "request_id": "7", + "work_id": "cosy_voice.1000", + "action": "exit" +} +``` + +响应 json: + +```json +{ + "created": 1761791854, + "data": "None", + "error": { + "code": 0, + "message": "" + }, + "object": "None", + "request_id": "7", + "work_id": "cosy_voice.1000" +} +``` + +error::code 为 0 表示执行成功。 + +## taskinfo + +获取任务列表。 + +发送 json: + +```json +{ + "request_id": "2", + "work_id": "cosy_voice", + "action": "taskinfo" +} +``` + +响应 json: + +```json +{ + "created": 1761791739, + "data": [ + "cosy_voice.1000" + ], + "error": { + "code": 0, + "message": "" + }, + "object": "llm.tasklist", + "request_id": "2", + "work_id": "cosy_voice" +} +``` + +获取任务运行参数。 + +```json +{ + "request_id": "2", + "work_id": "cosy_voice.1000", + "action": "taskinfo" +} +``` + +响应 json: + +```json +{ + "created": 1761791761, + "data": { + "enoutput": false, + "inputs": [ + "tts.utf-8" + ], + "model": "CosyVoice2-0.5B-ax650", + "response_format": "sys.pcm" + }, + "error": { + "code": 0, + "message": "" + }, + "object": "cosy_voice.taskinfo", + "request_id": "2", + "work_id": "cosy_voice.1000" +} +``` + +> **注意:work_id 是按照单元的初始化注册顺序增加的,并不是固定的索引值。** +> **同类型单元不能配置多个单元同时工作,否则会产生未知错误。例如 tts 和 melo tts 不能同时拍起用工作。** diff --git a/doc/projects_llm_framework_doc/llm_kws_en.md b/doc/projects_llm_framework_doc/llm_kws_en.md index 4ab85b47..84b2a666 100644 --- a/doc/projects_llm_framework_doc/llm_kws_en.md +++ b/doc/projects_llm_framework_doc/llm_kws_en.md @@ -34,7 +34,7 @@ Send JSON: - response_format: The result returned is in `kws.bool` format. - input: The input is `sys.pcm`, representing system audio. - enoutput: Whether to enable user result output. -- kws: The Chinese wake-up word is `"你好你好"`. +- kws: The English wake-up word is `"HELLO"`. It must be capital letters. - enwake_audio: Whether to enable wake-up audio output. Default is true. Response JSON: diff --git a/doc/projects_llm_framework_doc/llm_vlm_en.md b/doc/projects_llm_framework_doc/llm_vlm_en.md index 76196696..bbaa0d9c 100644 --- a/doc/projects_llm_framework_doc/llm_vlm_en.md +++ b/doc/projects_llm_framework_doc/llm_vlm_en.md @@ -15,7 +15,7 @@ Send the following JSON: "action": "setup", "object": "vlm.setup", "data": { - "model": "internvl2.5-1B-ax630c", + "model": "internvl2.5-1B-364-ax630c", "response_format": "vlm.utf-8.stream", "input": "vlm.utf-8", "enoutput": true, @@ -29,7 +29,7 @@ Send the following JSON: - work_id: Set to `vlm` when configuring the unit. - action: The method being called is `setup`. - object: Data type being transferred is `vlm.setup`. -- model: The model used is `internvl2.5-1B-ax630c`, a multimodal model. +- model: The model used is `internvl2.5-1B-364-ax630c`, a multimodal model. - response_format: The output is in `vlm.utf-8.stream`, a UTF-8 stream format. - input: The input is `vlm.utf-8`, representing user input. - enoutput: Specifies whether to enable user output. @@ -250,7 +250,7 @@ Example: "action": "setup", "object": "vlm.setup", "data": { - "model": "internvl2.5-1B-ax630c", + "model": "internvl2.5-1B-364-ax630c", "response_format": "vlm.utf-8.stream", "input": [ "vlm.utf-8", @@ -264,6 +264,38 @@ Example: } ``` +Linking the Output of the llm-camera Unit. + +Sending JSON: + +```json +{ + "request_id": "3", + "work_id": "vlm.1003", + "action": "link", + "object": "work_id", + "data": "camera.1000" +} +``` + +Response JSON: + +```json +{ + "created": 1750992545, + "data": "None", + "error": { + "code": 0, + "message": "" + }, + "object": "None", + "request_id": "3", + "work_id": "vlm.1003" +} +``` + +> **Ensure that the camera is properly configured and ready for operation when performing the link action. If using the AX630C MIPI camera, configure it in AI-ISP disabled mode during the initialization of llm-camera.** + ## unlink Unlink units. @@ -447,7 +479,7 @@ Response JSON: "vlm.utf-8", "kws.1000" ], - "model": "internvl2.5-1B-ax630c", + "model": "internvl2.5-1B-364-ax630c", "response_format": "vlm.utf-8.stream" }, "error": { diff --git a/doc/projects_llm_framework_doc/llm_vlm_zh.md b/doc/projects_llm_framework_doc/llm_vlm_zh.md index 161f48c1..ce797e5e 100644 --- a/doc/projects_llm_framework_doc/llm_vlm_zh.md +++ b/doc/projects_llm_framework_doc/llm_vlm_zh.md @@ -15,7 +15,7 @@ "action": "setup", "object": "vlm.setup", "data": { - "model": "internvl2.5-1B-ax630c", + "model": "internvl2.5-1B-364-ax630c", "response_format": "vlm.utf-8.stream", "input": "vlm.utf-8", "enoutput": true, @@ -29,7 +29,7 @@ - work_id:配置单元时,为 `vlm`。 - action:调用的方法为 `setup`。 - object:传输的数据类型为 `vlm.setup`。 -- model:使用的模型为 `internvl2.5-1B-ax630c` 多模态模型。 +- model:使用的模型为 `internvl2.5-1B-364-ax630c` 多模态模型。 - response_format:返回结果为 `vlm.utf-8.stream`, utf-8 的流式输出。 - input:输入的为 `vlm.utf-8`,代表的是从用户输入。 - enoutput:是否起用用户结果输出。 @@ -248,7 +248,7 @@ error::code 为 0 表示执行成功。 "action": "setup", "object": "vlm.setup", "data": { - "model": "internvl2.5-1B-ax630c", + "model": "internvl2.5-1B-364-ax630c", "response_format": "vlm.utf-8.stream", "input": [ "vlm.utf-8", @@ -262,6 +262,38 @@ error::code 为 0 表示执行成功。 } ``` +链接 llm-camera 单元的输出。 + +发送 json: + +```json +{ + "request_id": "3", + "work_id": "vlm.1003", + "action": "link", + "object": "work_id", + "data": "camera.1000" +} +``` + +响应 json: + +```json +{ + "created": 1750992545, + "data": "None", + "error": { + "code": 0, + "message": "" + }, + "object": "None", + "request_id": "3", + "work_id": "vlm.1003" +} +``` + +> **link 时必须保证 camera 此时已经配置好进入工作状态。当同时使用 AX630C MIPI 摄像头,需要在 llm-camera 初始化的时候配置为 AI-ISP 关闭模式。** + ## unlink 取消链接。 @@ -445,7 +477,7 @@ error::code 为 0 表示执行成功。 "vlm.utf-8", "kws.1000" ], - "model": "internvl2.5-1B-ax630c", + "model": "internvl2.5-1B-364-ax630c", "response_format": "vlm.utf-8.stream" }, "error": { diff --git a/ext_components/StackFlow/stackflow/StackFlow.cpp b/ext_components/StackFlow/stackflow/StackFlow.cpp index 2991162e..561e20f8 100644 --- a/ext_components/StackFlow/stackflow/StackFlow.cpp +++ b/ext_components/StackFlow/stackflow/StackFlow.cpp @@ -117,6 +117,11 @@ int llm_channel_obj::send_raw_to_pub(const std::string &raw) return zmq_[-1]->send_data(raw); } +int llm_channel_obj::send_raw_to_pub(const char *data, int size) +{ + return zmq_[-1]->send_data(data, size); +} + int llm_channel_obj::send_raw_to_usr(const std::string &raw) { if (zmq_[-2]) { diff --git a/ext_components/StackFlow/stackflow/StackFlow.h b/ext_components/StackFlow/stackflow/StackFlow.h index 25ac6743..c3424fa2 100644 --- a/ext_components/StackFlow/stackflow/StackFlow.h +++ b/ext_components/StackFlow/stackflow/StackFlow.h @@ -106,6 +106,7 @@ class llm_channel_obj { void stop_subscriber(const std::string &zmq_url); int check_zmq_errno(void *ctx, void *com, int code); int send_raw_to_pub(const std::string &raw); + int send_raw_to_pub(const char *data, int size); int send_raw_to_usr(const std::string &raw); template int output_data(const std::string &object, const T &data, const U &error_msg) diff --git a/ext_components/StackFlow/stackflow/pzmq.hpp b/ext_components/StackFlow/stackflow/pzmq.hpp index 5d51ac32..322c463c 100644 --- a/ext_components/StackFlow/stackflow/pzmq.hpp +++ b/ext_components/StackFlow/stackflow/pzmq.hpp @@ -127,7 +127,7 @@ class pzmq { if ((url[0] != 'i') && (url[1] != 'p')) { rpc_url_head_.clear(); } - if (mode_ != ZMQ_RPC_FUN) creat(url, raw_call); + creat(url, raw_call); } void set_timeout(int ms) { @@ -179,8 +179,6 @@ class pzmq { if (zmq_fun_.empty()) { std::string url = rpc_url_head_ + rpc_server_; mode_ = ZMQ_RPC_FUN; - zmq_fun_["list_action"] = - std::bind(&pzmq::_rpc_list_action, this, std::placeholders::_1, std::placeholders::_2); ret = creat(url); } zmq_fun_[action] = raw_call; @@ -330,6 +328,7 @@ class pzmq { inline int creat_rep(const std::string &url, const msg_callback_fun &raw_call) { int ret = zmq_bind(zmq_socket_, url.c_str()); + zmq_fun_["list_action"] = std::bind(&pzmq::_rpc_list_action, this, std::placeholders::_1, std::placeholders::_2); flage_ = false; zmq_thread_ = std::make_unique(std::bind(&pzmq::zmq_event_loop, this, raw_call)); return ret; @@ -382,7 +381,7 @@ class pzmq { std::unique_lock lock(zmq_fun_mtx_); retval = zmq_fun_.at(msg_ptr->string())(this, msg1_ptr); } catch (...) { - retval = "NotAction"; + retval = msg_ptr->string() + " NotAction"; } zmq_send(zmq_socket_, retval.c_str(), retval.length(), 0); msg1_ptr.reset(); @@ -394,6 +393,8 @@ class pzmq { } void close_zmq() { + int linger = 1000; + zmq_setsockopt(zmq_socket_, ZMQ_LINGER, &linger, sizeof(linger)); zmq_close(zmq_socket_); zmq_ctx_destroy(zmq_ctx_); if ((mode_ == ZMQ_PUB) || (mode_ == ZMQ_PULL) || (mode_ == ZMQ_RPC_FUN)) { diff --git a/ext_components/ax_msp/Kconfig b/ext_components/ax_msp/Kconfig index 73824242..ef6a29d2 100644 --- a/ext_components/ax_msp/Kconfig +++ b/ext_components/ax_msp/Kconfig @@ -12,8 +12,8 @@ menuconfig AX_MSP_ENABLED bool "enable ax620e bsp" help build by AXERA! - config AX_650N_MSP_ENABLED - bool "enable ax650n bsp" + config AX_650C_MSP_ENABLED + bool "enable ax650C bsp" help build by AXERA! config AX_520_MSP_ENABLED @@ -25,17 +25,23 @@ menuconfig AX_MSP_ENABLED choice prompt "choice common version" default MSP_V2_0_0_ENABLED - depends on AX_MSP_ENABLED - config MSP_V3_0_0_ENABLED - bool "enable v3.0.0 bsp" - help - build by m5stack! + depends on AX_MSP_ENABLED && AX_620E_MSP_ENABLED config MSP_V2_0_0_ENABLED bool "enable v2.0.0 bsp" help build by m5stack! endchoice - + + choice + prompt "choice common version" + default MSP_V3_6_2_ENABLED + depends on AX_MSP_ENABLED && AX_650C_MSP_ENABLED + config MSP_V3_6_2_ENABLED + bool "enable v3.6.2 bsp" + help + build by m5stack! + endchoice + config SAMPLE_COMMON_ENABLED bool "Enable sample common" default n diff --git a/ext_components/ax_msp/SConstruct b/ext_components/ax_msp/SConstruct index a77c7d46..696c5655 100644 --- a/ext_components/ax_msp/SConstruct +++ b/ext_components/ax_msp/SConstruct @@ -29,6 +29,7 @@ if 'CONFIG_AX_620E_MSP_ENABLED' in os.environ: for dirn in third_party: INCLUDE.append(os.path.join(MSP_PATH,'third-party',dirn,'include')) LINK_SEARCH_PATH.append(os.path.join(MSP_PATH,'third-party',dirn,'lib/arm64/glibc')) + INCLUDE.append(os.path.join(MSP_PATH,'third-party/tinyalsa/include/tinyalsa')) INCLUDE.append(os.path.join(MSP_PATH,'third-party/live/out/arm64/glibc/include')) LINK_SEARCH_PATH.append(os.path.join(MSP_PATH,'third-party/live/out/arm64/glibc/lib')) INCLUDE.append(os.path.join(MSP_PATH,'third-party/openssl/arm64/include')) @@ -54,3 +55,60 @@ if 'CONFIG_AX_620E_MSP_ENABLED' in os.environ: 'REGISTER':'static' }) +if 'CONFIG_AX_650C_MSP_ENABLED' in os.environ: + MSP_PATH = '' + if 'CONFIG_MSP_V3_6_2_ENABLED' in os.environ: + MSP_PATH = os.environ.get('EXT_MSP_PATH', check_wget_down("https://m5stack.oss-cn-shenzhen.aliyuncs.com/resource/linux/llm/m5stack_ax650n_msp.tar.gz", 'm5stack_ax650n_msp.tar.gz')) + + SRCS=[] + INCLUDE=[] + PRIVATE_INCLUDE=[] + REQUIREMENTS=[] + STATIC_LIB=[] + DYNAMIC_LIB=[] + DEFINITIONS=[] + DEFINITIONS_PRIVATE=[''] + LDFLAGS=[] + LINK_SEARCH_PATH=[] + + env["MSP_PATH"] = MSP_PATH + # , os.path.join(MSP_PATH, 'sample/common') + INCLUDE += [os.path.join(MSP_PATH, 'out/include'), os.path.join(MSP_PATH, 'sample'), os.path.join(MSP_PATH, 'sample/rtsp')] + LINK_SEARCH_PATH += [os.path.join(MSP_PATH, 'out/lib')] + REQUIREMENTS += ['dl', 'm', 'pthread'] + third_party = ['drm','faac','fdk-aac','ffmpeg','libsamplerate','mp4','opencv','opus','tinyalsa'] + for dirn in third_party: + INCLUDE.append(os.path.join(MSP_PATH,'third-party',dirn,'include')) + LINK_SEARCH_PATH.append(os.path.join(MSP_PATH,'third-party',dirn,'lib/arm64/glibc')) + INCLUDE.append(os.path.join(MSP_PATH,'third-party/tinyalsa/include/tinyalsa')) + INCLUDE.append(os.path.join(MSP_PATH,'third-party/live/out/include/liveMedia')) + INCLUDE.append(os.path.join(MSP_PATH,'third-party/live/out/include/groupsock')) + INCLUDE.append(os.path.join(MSP_PATH,'third-party/live/out/include/UsageEnvironment')) + INCLUDE.append(os.path.join(MSP_PATH,'third-party/live/out/include/BasicUsageEnvironment')) + INCLUDE.append(os.path.join(MSP_PATH,'component/isp_proton/sensor/platform/tcm')) + LINK_SEARCH_PATH.append(os.path.join(MSP_PATH,'third-party/libsamplerate/lib')) + INCLUDE.append(os.path.join(MSP_PATH,'third-party/openssl/include')) + LINK_SEARCH_PATH.append(os.path.join(MSP_PATH,'third-party/openssl/arm64/glibc/lib')) + LINK_SEARCH_PATH.append(os.path.join(MSP_PATH,'third-party/tinyalsa/lib')) + LINK_SEARCH_PATH.append(os.path.join(MSP_PATH,'third-party/fdk-aac/lib')) + LINK_SEARCH_PATH.append(os.path.join(MSP_PATH,'third-party/opus/lib')) + LINK_SEARCH_PATH.append(os.path.join(MSP_PATH,'app/lib')) + + if 'CONFIG_SAMPLE_COMMON_ENABLED' in os.environ: + if 'CONFIG_MSP_V3_0_0_ENABLED' in os.environ: + INCLUDE.append(os.path.join(MSP_PATH,'sample/common')) + SRCS += AGlob(os.path.join(MSP_PATH,'sample/common/*.c*')) + + env['COMPONENTS'].append({'target':os.path.basename(env['component_dir']), + 'SRCS':SRCS, + 'INCLUDE':INCLUDE, + 'PRIVATE_INCLUDE':PRIVATE_INCLUDE, + 'REQUIREMENTS':REQUIREMENTS, + 'STATIC_LIB':STATIC_LIB, + 'DYNAMIC_LIB':DYNAMIC_LIB, + 'DEFINITIONS':DEFINITIONS, + 'DEFINITIONS_PRIVATE':DEFINITIONS_PRIVATE, + 'LDFLAGS':LDFLAGS, + 'LINK_SEARCH_PATH':LINK_SEARCH_PATH, + 'REGISTER':'static' + }) \ No newline at end of file diff --git a/ext_components/tokenizer/Kconfig b/ext_components/tokenizer/Kconfig new file mode 100644 index 00000000..1cf11388 --- /dev/null +++ b/ext_components/tokenizer/Kconfig @@ -0,0 +1,5 @@ +menuconfig AX_TOKENIZER_ENABLED + bool "Enable tokenizer support" + default n + help + enable tokenizer support \ No newline at end of file diff --git a/ext_components/tokenizer/SConstruct b/ext_components/tokenizer/SConstruct new file mode 100644 index 00000000..e393f25f --- /dev/null +++ b/ext_components/tokenizer/SConstruct @@ -0,0 +1,52 @@ +# component2/SConscript +Import("env") +import os +from pathlib import Path + +with open(env["PROJECT_TOOL_S"]) as f: + exec(f.read()) + +_SDK_PATH = os.path.normpath( + os.environ.get("SDK_PATH", str(Path(os.getcwd()) / ".." / "..")) +) + +env["GIT_REPO_LISTS"]["tokenizer"] = { + "url": "https://github.com/ZHEQIUSHUI/tokenizer.git", + "commit": "83f41d4b5b9a135c167d44fcdf2a0c56ebacca6d", + "path": str(Path(_SDK_PATH) / "github_source" / "tokenizer"), +} + +if "CONFIG_AX_TOKENIZER_ENABLED" in os.environ: + check_component("tokenizer") + SRCS = [] + INCLUDE = [] + PRIVATE_INCLUDE = [] + REQUIREMENTS = [] + STATIC_LIB = [] + DYNAMIC_LIB = [] + DEFINITIONS = [] + DEFINITIONS_PRIVATE = [] + LDFLAGS = [] + LINK_SEARCH_PATH = [] + + INCLUDE += [ + os.path.join(env["GIT_REPO_LISTS"]["tokenizer"]["path"], "include"), + ] + print("AX-TOKENIZER INCLUDE:", INCLUDE) + + env["COMPONENTS"].append( + { + "target": os.path.basename(env["component_dir"]), + "SRCS": SRCS, + "INCLUDE": INCLUDE, + "PRIVATE_INCLUDE": PRIVATE_INCLUDE, + "REQUIREMENTS": REQUIREMENTS, + "STATIC_LIB": STATIC_LIB, + "DYNAMIC_LIB": DYNAMIC_LIB, + "DEFINITIONS": DEFINITIONS, + "DEFINITIONS_PRIVATE": DEFINITIONS_PRIVATE, + "LDFLAGS": LDFLAGS, + "LINK_SEARCH_PATH": LINK_SEARCH_PATH, + "REGISTER": "static", + } + ) \ No newline at end of file diff --git a/projects/llm_framework/README.md b/projects/llm_framework/README.md index e99981c3..10699700 100644 --- a/projects/llm_framework/README.md +++ b/projects/llm_framework/README.md @@ -98,7 +98,7 @@ send : "action": "setup", "object": "melotts.setup", "data": { - "model": "melotts_zh-cn", + "model": "melotts-zh-cn", "response_format": "sys.pcm", "input": "tts.utf-8", "enoutput": false diff --git a/projects/llm_framework/SConstruct b/projects/llm_framework/SConstruct index 5d014ef6..731210de 100644 --- a/projects/llm_framework/SConstruct +++ b/projects/llm_framework/SConstruct @@ -5,7 +5,7 @@ import shutil os.environ['SDK_PATH'] = os.path.normpath(str(Path(os.getcwd())/'..'/'..'/'SDK')) os.environ['EXT_COMPONENTS_PATH'] = os.path.normpath(str(Path(os.getcwd())/'..'/'..'/'ext_components')) -version = 'v0.0.7' +version = 'v0.1.3' static_lib = 'static_lib' update = False diff --git a/projects/llm_framework/config_defaults.mk b/projects/llm_framework/config_defaults.mk index 09d6a4b6..898c48a5 100644 --- a/projects/llm_framework/config_defaults.mk +++ b/projects/llm_framework/config_defaults.mk @@ -23,3 +23,4 @@ CONFIG_SINGLE_HEADER_LIBS_ENABLED=y CONFIG_AX_SAMPLES_ENABLED=y CONFIG_SIMDJSON_COMPENENT_ENABLED=y CONFIG_SAMPLE_COMMON_ENABLED=y +CONFIG_MODBUS_ENABLED=y \ No newline at end of file diff --git a/projects/llm_framework/include/abseil-cpp/absl/algorithm/algorithm.h b/projects/llm_framework/include/abseil-cpp/absl/algorithm/algorithm.h deleted file mode 100644 index 59aeed7d..00000000 --- a/projects/llm_framework/include/abseil-cpp/absl/algorithm/algorithm.h +++ /dev/null @@ -1,64 +0,0 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// ----------------------------------------------------------------------------- -// File: algorithm.h -// ----------------------------------------------------------------------------- -// -// This header file contains Google extensions to the standard C++ -// header. - -#ifndef ABSL_ALGORITHM_ALGORITHM_H_ -#define ABSL_ALGORITHM_ALGORITHM_H_ - -#include -#include -#include - -#include "absl/base/config.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN - -// equal() -// rotate() -// -// Historical note: Abseil once provided implementations of these algorithms -// prior to their adoption in C++14. New code should prefer to use the std -// variants. -// -// See the documentation for the STL header for more information: -// https://en.cppreference.com/w/cpp/header/algorithm -using std::equal; -using std::rotate; - -// linear_search() -// -// Performs a linear search for `value` using the iterator `first` up to -// but not including `last`, returning true if [`first`, `last`) contains an -// element equal to `value`. -// -// A linear search is of O(n) complexity which is guaranteed to make at most -// n = (`last` - `first`) comparisons. A linear search over short containers -// may be faster than a binary search, even when the container is sorted. -template -bool linear_search(InputIterator first, InputIterator last, - const EqualityComparable& value) { - return std::find(first, last, value) != last; -} - -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_ALGORITHM_ALGORITHM_H_ diff --git a/projects/llm_framework/include/abseil-cpp/absl/algorithm/container.h b/projects/llm_framework/include/abseil-cpp/absl/algorithm/container.h deleted file mode 100644 index c7bafae1..00000000 --- a/projects/llm_framework/include/abseil-cpp/absl/algorithm/container.h +++ /dev/null @@ -1,1760 +0,0 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// ----------------------------------------------------------------------------- -// File: container.h -// ----------------------------------------------------------------------------- -// -// This header file provides Container-based versions of algorithmic functions -// within the C++ standard library. The following standard library sets of -// functions are covered within this file: -// -// * Algorithmic functions -// * Algorithmic functions -// * functions -// -// The standard library functions operate on iterator ranges; the functions -// within this API operate on containers, though many return iterator ranges. -// -// All functions within this API are named with a `c_` prefix. Calls such as -// `absl::c_xx(container, ...) are equivalent to std:: functions such as -// `std::xx(std::begin(cont), std::end(cont), ...)`. Functions that act on -// iterators but not conceptually on iterator ranges (e.g. `std::iter_swap`) -// have no equivalent here. -// -// For template parameter and variable naming, `C` indicates the container type -// to which the function is applied, `Pred` indicates the predicate object type -// to be used by the function and `T` indicates the applicable element type. - -#ifndef ABSL_ALGORITHM_CONTAINER_H_ -#define ABSL_ALGORITHM_CONTAINER_H_ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "absl/algorithm/algorithm.h" -#include "absl/base/macros.h" -#include "absl/base/nullability.h" -#include "absl/meta/type_traits.h" - -namespace absl { -ABSL_NAMESPACE_BEGIN -namespace container_algorithm_internal { - -// NOTE: it is important to defer to ADL lookup for building with C++ modules, -// especially for headers like which are not visible from this file -// but specialize std::begin and std::end. -using std::begin; -using std::end; - -// The type of the iterator given by begin(c) (possibly std::begin(c)). -// ContainerIter> gives vector::const_iterator, -// while ContainerIter> gives vector::iterator. -template -using ContainerIter = decltype(begin(std::declval())); - -// An MSVC bug involving template parameter substitution requires us to use -// decltype() here instead of just std::pair. -template -using ContainerIterPairType = - decltype(std::make_pair(ContainerIter(), ContainerIter())); - -template -using ContainerDifferenceType = decltype(std::distance( - std::declval>(), std::declval>())); - -template -using ContainerPointerType = - typename std::iterator_traits>::pointer; - -// container_algorithm_internal::c_begin and -// container_algorithm_internal::c_end are abbreviations for proper ADL -// lookup of std::begin and std::end, i.e. -// using std::begin; -// using std::end; -// std::foo(begin(c), end(c)); -// becomes -// std::foo(container_algorithm_internal::begin(c), -// container_algorithm_internal::end(c)); -// These are meant for internal use only. - -template -ContainerIter c_begin(C& c) { - return begin(c); -} - -template -ContainerIter c_end(C& c) { - return end(c); -} - -template -struct IsUnorderedContainer : std::false_type {}; - -template -struct IsUnorderedContainer< - std::unordered_map> : std::true_type {}; - -template -struct IsUnorderedContainer> - : std::true_type {}; - -} // namespace container_algorithm_internal - -// PUBLIC API - -//------------------------------------------------------------------------------ -// Abseil algorithm.h functions -//------------------------------------------------------------------------------ - -// c_linear_search() -// -// Container-based version of absl::linear_search() for performing a linear -// search within a container. -template -bool c_linear_search(const C& c, EqualityComparable&& value) { - return linear_search(container_algorithm_internal::c_begin(c), - container_algorithm_internal::c_end(c), - std::forward(value)); -} - -//------------------------------------------------------------------------------ -// algorithms -//------------------------------------------------------------------------------ - -// c_distance() -// -// Container-based version of the `std::distance()` function to -// return the number of elements within a container. -template -container_algorithm_internal::ContainerDifferenceType c_distance( - const C& c) { - return std::distance(container_algorithm_internal::c_begin(c), - container_algorithm_internal::c_end(c)); -} - -//------------------------------------------------------------------------------ -// Non-modifying sequence operations -//------------------------------------------------------------------------------ - -// c_all_of() -// -// Container-based version of the `std::all_of()` function to -// test if all elements within a container satisfy a condition. -template -bool c_all_of(const C& c, Pred&& pred) { - return std::all_of(container_algorithm_internal::c_begin(c), - container_algorithm_internal::c_end(c), - std::forward(pred)); -} - -// c_any_of() -// -// Container-based version of the `std::any_of()` function to -// test if any element in a container fulfills a condition. -template -bool c_any_of(const C& c, Pred&& pred) { - return std::any_of(container_algorithm_internal::c_begin(c), - container_algorithm_internal::c_end(c), - std::forward(pred)); -} - -// c_none_of() -// -// Container-based version of the `std::none_of()` function to -// test if no elements in a container fulfill a condition. -template -bool c_none_of(const C& c, Pred&& pred) { - return std::none_of(container_algorithm_internal::c_begin(c), - container_algorithm_internal::c_end(c), - std::forward(pred)); -} - -// c_for_each() -// -// Container-based version of the `std::for_each()` function to -// apply a function to a container's elements. -template -decay_t c_for_each(C&& c, Function&& f) { - return std::for_each(container_algorithm_internal::c_begin(c), - container_algorithm_internal::c_end(c), - std::forward(f)); -} - -// c_find() -// -// Container-based version of the `std::find()` function to find -// the first element containing the passed value within a container value. -template -container_algorithm_internal::ContainerIter c_find(C& c, T&& value) { - return std::find(container_algorithm_internal::c_begin(c), - container_algorithm_internal::c_end(c), - std::forward(value)); -} - -// c_find_if() -// -// Container-based version of the `std::find_if()` function to find -// the first element in a container matching the given condition. -template -container_algorithm_internal::ContainerIter c_find_if(C& c, Pred&& pred) { - return std::find_if(container_algorithm_internal::c_begin(c), - container_algorithm_internal::c_end(c), - std::forward(pred)); -} - -// c_find_if_not() -// -// Container-based version of the `std::find_if_not()` function to -// find the first element in a container not matching the given condition. -template -container_algorithm_internal::ContainerIter c_find_if_not(C& c, - Pred&& pred) { - return std::find_if_not(container_algorithm_internal::c_begin(c), - container_algorithm_internal::c_end(c), - std::forward(pred)); -} - -// c_find_end() -// -// Container-based version of the `std::find_end()` function to -// find the last subsequence within a container. -template -container_algorithm_internal::ContainerIter c_find_end( - Sequence1& sequence, Sequence2& subsequence) { - return std::find_end(container_algorithm_internal::c_begin(sequence), - container_algorithm_internal::c_end(sequence), - container_algorithm_internal::c_begin(subsequence), - container_algorithm_internal::c_end(subsequence)); -} - -// Overload of c_find_end() for using a predicate evaluation other than `==` as -// the function's test condition. -template -container_algorithm_internal::ContainerIter c_find_end( - Sequence1& sequence, Sequence2& subsequence, BinaryPredicate&& pred) { - return std::find_end(container_algorithm_internal::c_begin(sequence), - container_algorithm_internal::c_end(sequence), - container_algorithm_internal::c_begin(subsequence), - container_algorithm_internal::c_end(subsequence), - std::forward(pred)); -} - -// c_find_first_of() -// -// Container-based version of the `std::find_first_of()` function to -// find the first element within the container that is also within the options -// container. -template -container_algorithm_internal::ContainerIter c_find_first_of(C1& container, - C2& options) { - return std::find_first_of(container_algorithm_internal::c_begin(container), - container_algorithm_internal::c_end(container), - container_algorithm_internal::c_begin(options), - container_algorithm_internal::c_end(options)); -} - -// Overload of c_find_first_of() for using a predicate evaluation other than -// `==` as the function's test condition. -template -container_algorithm_internal::ContainerIter c_find_first_of( - C1& container, C2& options, BinaryPredicate&& pred) { - return std::find_first_of(container_algorithm_internal::c_begin(container), - container_algorithm_internal::c_end(container), - container_algorithm_internal::c_begin(options), - container_algorithm_internal::c_end(options), - std::forward(pred)); -} - -// c_adjacent_find() -// -// Container-based version of the `std::adjacent_find()` function to -// find equal adjacent elements within a container. -template -container_algorithm_internal::ContainerIter c_adjacent_find( - Sequence& sequence) { - return std::adjacent_find(container_algorithm_internal::c_begin(sequence), - container_algorithm_internal::c_end(sequence)); -} - -// Overload of c_adjacent_find() for using a predicate evaluation other than -// `==` as the function's test condition. -template -container_algorithm_internal::ContainerIter c_adjacent_find( - Sequence& sequence, BinaryPredicate&& pred) { - return std::adjacent_find(container_algorithm_internal::c_begin(sequence), - container_algorithm_internal::c_end(sequence), - std::forward(pred)); -} - -// c_count() -// -// Container-based version of the `std::count()` function to count -// values that match within a container. -template -container_algorithm_internal::ContainerDifferenceType c_count( - const C& c, T&& value) { - return std::count(container_algorithm_internal::c_begin(c), - container_algorithm_internal::c_end(c), - std::forward(value)); -} - -// c_count_if() -// -// Container-based version of the `std::count_if()` function to -// count values matching a condition within a container. -template -container_algorithm_internal::ContainerDifferenceType c_count_if( - const C& c, Pred&& pred) { - return std::count_if(container_algorithm_internal::c_begin(c), - container_algorithm_internal::c_end(c), - std::forward(pred)); -} - -// c_mismatch() -// -// Container-based version of the `std::mismatch()` function to -// return the first element where two ordered containers differ. Applies `==` to -// the first N elements of `c1` and `c2`, where N = min(size(c1), size(c2)). -template -container_algorithm_internal::ContainerIterPairType c_mismatch(C1& c1, - C2& c2) { - return std::mismatch(container_algorithm_internal::c_begin(c1), - container_algorithm_internal::c_end(c1), - container_algorithm_internal::c_begin(c2), - container_algorithm_internal::c_end(c2)); -} - -// Overload of c_mismatch() for using a predicate evaluation other than `==` as -// the function's test condition. Applies `pred`to the first N elements of `c1` -// and `c2`, where N = min(size(c1), size(c2)). -template -container_algorithm_internal::ContainerIterPairType c_mismatch( - C1& c1, C2& c2, BinaryPredicate pred) { - return std::mismatch(container_algorithm_internal::c_begin(c1), - container_algorithm_internal::c_end(c1), - container_algorithm_internal::c_begin(c2), - container_algorithm_internal::c_end(c2), pred); -} - -// c_equal() -// -// Container-based version of the `std::equal()` function to -// test whether two containers are equal. -template -bool c_equal(const C1& c1, const C2& c2) { - return std::equal(container_algorithm_internal::c_begin(c1), - container_algorithm_internal::c_end(c1), - container_algorithm_internal::c_begin(c2), - container_algorithm_internal::c_end(c2)); -} - -// Overload of c_equal() for using a predicate evaluation other than `==` as -// the function's test condition. -template -bool c_equal(const C1& c1, const C2& c2, BinaryPredicate&& pred) { - return std::equal(container_algorithm_internal::c_begin(c1), - container_algorithm_internal::c_end(c1), - container_algorithm_internal::c_begin(c2), - container_algorithm_internal::c_end(c2), - std::forward(pred)); -} - -// c_is_permutation() -// -// Container-based version of the `std::is_permutation()` function -// to test whether a container is a permutation of another. -template -bool c_is_permutation(const C1& c1, const C2& c2) { - return std::is_permutation(container_algorithm_internal::c_begin(c1), - container_algorithm_internal::c_end(c1), - container_algorithm_internal::c_begin(c2), - container_algorithm_internal::c_end(c2)); -} - -// Overload of c_is_permutation() for using a predicate evaluation other than -// `==` as the function's test condition. -template -bool c_is_permutation(const C1& c1, const C2& c2, BinaryPredicate&& pred) { - return std::is_permutation(container_algorithm_internal::c_begin(c1), - container_algorithm_internal::c_end(c1), - container_algorithm_internal::c_begin(c2), - container_algorithm_internal::c_end(c2), - std::forward(pred)); -} - -// c_search() -// -// Container-based version of the `std::search()` function to search -// a container for a subsequence. -template -container_algorithm_internal::ContainerIter c_search( - Sequence1& sequence, Sequence2& subsequence) { - return std::search(container_algorithm_internal::c_begin(sequence), - container_algorithm_internal::c_end(sequence), - container_algorithm_internal::c_begin(subsequence), - container_algorithm_internal::c_end(subsequence)); -} - -// Overload of c_search() for using a predicate evaluation other than -// `==` as the function's test condition. -template -container_algorithm_internal::ContainerIter c_search( - Sequence1& sequence, Sequence2& subsequence, BinaryPredicate&& pred) { - return std::search(container_algorithm_internal::c_begin(sequence), - container_algorithm_internal::c_end(sequence), - container_algorithm_internal::c_begin(subsequence), - container_algorithm_internal::c_end(subsequence), - std::forward(pred)); -} - -// c_search_n() -// -// Container-based version of the `std::search_n()` function to -// search a container for the first sequence of N elements. -template -container_algorithm_internal::ContainerIter c_search_n( - Sequence& sequence, Size count, T&& value) { - return std::search_n(container_algorithm_internal::c_begin(sequence), - container_algorithm_internal::c_end(sequence), count, - std::forward(value)); -} - -// Overload of c_search_n() for using a predicate evaluation other than -// `==` as the function's test condition. -template -container_algorithm_internal::ContainerIter c_search_n( - Sequence& sequence, Size count, T&& value, BinaryPredicate&& pred) { - return std::search_n(container_algorithm_internal::c_begin(sequence), - container_algorithm_internal::c_end(sequence), count, - std::forward(value), - std::forward(pred)); -} - -//------------------------------------------------------------------------------ -// Modifying sequence operations -//------------------------------------------------------------------------------ - -// c_copy() -// -// Container-based version of the `std::copy()` function to copy a -// container's elements into an iterator. -template -OutputIterator c_copy(const InputSequence& input, OutputIterator output) { - return std::copy(container_algorithm_internal::c_begin(input), - container_algorithm_internal::c_end(input), output); -} - -// c_copy_n() -// -// Container-based version of the `std::copy_n()` function to copy a -// container's first N elements into an iterator. -template -OutputIterator c_copy_n(const C& input, Size n, OutputIterator output) { - return std::copy_n(container_algorithm_internal::c_begin(input), n, output); -} - -// c_copy_if() -// -// Container-based version of the `std::copy_if()` function to copy -// a container's elements satisfying some condition into an iterator. -template -OutputIterator c_copy_if(const InputSequence& input, OutputIterator output, - Pred&& pred) { - return std::copy_if(container_algorithm_internal::c_begin(input), - container_algorithm_internal::c_end(input), output, - std::forward(pred)); -} - -// c_copy_backward() -// -// Container-based version of the `std::copy_backward()` function to -// copy a container's elements in reverse order into an iterator. -template -BidirectionalIterator c_copy_backward(const C& src, - BidirectionalIterator dest) { - return std::copy_backward(container_algorithm_internal::c_begin(src), - container_algorithm_internal::c_end(src), dest); -} - -// c_move() -// -// Container-based version of the `std::move()` function to move -// a container's elements into an iterator. -template -OutputIterator c_move(C&& src, OutputIterator dest) { - return std::move(container_algorithm_internal::c_begin(src), - container_algorithm_internal::c_end(src), dest); -} - -// c_move_backward() -// -// Container-based version of the `std::move_backward()` function to -// move a container's elements into an iterator in reverse order. -template -BidirectionalIterator c_move_backward(C&& src, BidirectionalIterator dest) { - return std::move_backward(container_algorithm_internal::c_begin(src), - container_algorithm_internal::c_end(src), dest); -} - -// c_swap_ranges() -// -// Container-based version of the `std::swap_ranges()` function to -// swap a container's elements with another container's elements. Swaps the -// first N elements of `c1` and `c2`, where N = min(size(c1), size(c2)). -template -container_algorithm_internal::ContainerIter c_swap_ranges(C1& c1, C2& c2) { - auto first1 = container_algorithm_internal::c_begin(c1); - auto last1 = container_algorithm_internal::c_end(c1); - auto first2 = container_algorithm_internal::c_begin(c2); - auto last2 = container_algorithm_internal::c_end(c2); - - using std::swap; - for (; first1 != last1 && first2 != last2; ++first1, (void)++first2) { - swap(*first1, *first2); - } - return first2; -} - -// c_transform() -// -// Container-based version of the `std::transform()` function to -// transform a container's elements using the unary operation, storing the -// result in an iterator pointing to the last transformed element in the output -// range. -template -OutputIterator c_transform(const InputSequence& input, OutputIterator output, - UnaryOp&& unary_op) { - return std::transform(container_algorithm_internal::c_begin(input), - container_algorithm_internal::c_end(input), output, - std::forward(unary_op)); -} - -// Overload of c_transform() for performing a transformation using a binary -// predicate. Applies `binary_op` to the first N elements of `c1` and `c2`, -// where N = min(size(c1), size(c2)). -template -OutputIterator c_transform(const InputSequence1& input1, - const InputSequence2& input2, OutputIterator output, - BinaryOp&& binary_op) { - auto first1 = container_algorithm_internal::c_begin(input1); - auto last1 = container_algorithm_internal::c_end(input1); - auto first2 = container_algorithm_internal::c_begin(input2); - auto last2 = container_algorithm_internal::c_end(input2); - for (; first1 != last1 && first2 != last2; - ++first1, (void)++first2, ++output) { - *output = binary_op(*first1, *first2); - } - - return output; -} - -// c_replace() -// -// Container-based version of the `std::replace()` function to -// replace a container's elements of some value with a new value. The container -// is modified in place. -template -void c_replace(Sequence& sequence, const T& old_value, const T& new_value) { - std::replace(container_algorithm_internal::c_begin(sequence), - container_algorithm_internal::c_end(sequence), old_value, - new_value); -} - -// c_replace_if() -// -// Container-based version of the `std::replace_if()` function to -// replace a container's elements of some value with a new value based on some -// condition. The container is modified in place. -template -void c_replace_if(C& c, Pred&& pred, T&& new_value) { - std::replace_if(container_algorithm_internal::c_begin(c), - container_algorithm_internal::c_end(c), - std::forward(pred), std::forward(new_value)); -} - -// c_replace_copy() -// -// Container-based version of the `std::replace_copy()` function to -// replace a container's elements of some value with a new value and return the -// results within an iterator. -template -OutputIterator c_replace_copy(const C& c, OutputIterator result, T&& old_value, - T&& new_value) { - return std::replace_copy(container_algorithm_internal::c_begin(c), - container_algorithm_internal::c_end(c), result, - std::forward(old_value), - std::forward(new_value)); -} - -// c_replace_copy_if() -// -// Container-based version of the `std::replace_copy_if()` function -// to replace a container's elements of some value with a new value based on -// some condition, and return the results within an iterator. -template -OutputIterator c_replace_copy_if(const C& c, OutputIterator result, Pred&& pred, - const T& new_value) { - return std::replace_copy_if(container_algorithm_internal::c_begin(c), - container_algorithm_internal::c_end(c), result, - std::forward(pred), new_value); -} - -// c_fill() -// -// Container-based version of the `std::fill()` function to fill a -// container with some value. -template -void c_fill(C& c, const T& value) { - std::fill(container_algorithm_internal::c_begin(c), - container_algorithm_internal::c_end(c), value); -} - -// c_fill_n() -// -// Container-based version of the `std::fill_n()` function to fill -// the first N elements in a container with some value. -template -void c_fill_n(C& c, Size n, const T& value) { - std::fill_n(container_algorithm_internal::c_begin(c), n, value); -} - -// c_generate() -// -// Container-based version of the `std::generate()` function to -// assign a container's elements to the values provided by the given generator. -template -void c_generate(C& c, Generator&& gen) { - std::generate(container_algorithm_internal::c_begin(c), - container_algorithm_internal::c_end(c), - std::forward(gen)); -} - -// c_generate_n() -// -// Container-based version of the `std::generate_n()` function to -// assign a container's first N elements to the values provided by the given -// generator. -template -container_algorithm_internal::ContainerIter c_generate_n(C& c, Size n, - Generator&& gen) { - return std::generate_n(container_algorithm_internal::c_begin(c), n, - std::forward(gen)); -} - -// Note: `c_xx()` container versions for `remove()`, `remove_if()`, -// and `unique()` are omitted, because it's not clear whether or not such -// functions should call erase on their supplied sequences afterwards. Either -// behavior would be surprising for a different set of users. - -// c_remove_copy() -// -// Container-based version of the `std::remove_copy()` function to -// copy a container's elements while removing any elements matching the given -// `value`. -template -OutputIterator c_remove_copy(const C& c, OutputIterator result, - const T& value) { - return std::remove_copy(container_algorithm_internal::c_begin(c), - container_algorithm_internal::c_end(c), result, - value); -} - -// c_remove_copy_if() -// -// Container-based version of the `std::remove_copy_if()` function -// to copy a container's elements while removing any elements matching the given -// condition. -template -OutputIterator c_remove_copy_if(const C& c, OutputIterator result, - Pred&& pred) { - return std::remove_copy_if(container_algorithm_internal::c_begin(c), - container_algorithm_internal::c_end(c), result, - std::forward(pred)); -} - -// c_unique_copy() -// -// Container-based version of the `std::unique_copy()` function to -// copy a container's elements while removing any elements containing duplicate -// values. -template -OutputIterator c_unique_copy(const C& c, OutputIterator result) { - return std::unique_copy(container_algorithm_internal::c_begin(c), - container_algorithm_internal::c_end(c), result); -} - -// Overload of c_unique_copy() for using a predicate evaluation other than -// `==` for comparing uniqueness of the element values. -template -OutputIterator c_unique_copy(const C& c, OutputIterator result, - BinaryPredicate&& pred) { - return std::unique_copy(container_algorithm_internal::c_begin(c), - container_algorithm_internal::c_end(c), result, - std::forward(pred)); -} - -// c_reverse() -// -// Container-based version of the `std::reverse()` function to -// reverse a container's elements. -template -void c_reverse(Sequence& sequence) { - std::reverse(container_algorithm_internal::c_begin(sequence), - container_algorithm_internal::c_end(sequence)); -} - -// c_reverse_copy() -// -// Container-based version of the `std::reverse()` function to -// reverse a container's elements and write them to an iterator range. -template -OutputIterator c_reverse_copy(const C& sequence, OutputIterator result) { - return std::reverse_copy(container_algorithm_internal::c_begin(sequence), - container_algorithm_internal::c_end(sequence), - result); -} - -// c_rotate() -// -// Container-based version of the `std::rotate()` function to -// shift a container's elements leftward such that the `middle` element becomes -// the first element in the container. -template > -Iterator c_rotate(C& sequence, Iterator middle) { - return absl::rotate(container_algorithm_internal::c_begin(sequence), middle, - container_algorithm_internal::c_end(sequence)); -} - -// c_rotate_copy() -// -// Container-based version of the `std::rotate_copy()` function to -// shift a container's elements leftward such that the `middle` element becomes -// the first element in a new iterator range. -template -OutputIterator c_rotate_copy( - const C& sequence, - container_algorithm_internal::ContainerIter middle, - OutputIterator result) { - return std::rotate_copy(container_algorithm_internal::c_begin(sequence), - middle, container_algorithm_internal::c_end(sequence), - result); -} - -// c_shuffle() -// -// Container-based version of the `std::shuffle()` function to -// randomly shuffle elements within the container using a `gen()` uniform random -// number generator. -template -void c_shuffle(RandomAccessContainer& c, UniformRandomBitGenerator&& gen) { - std::shuffle(container_algorithm_internal::c_begin(c), - container_algorithm_internal::c_end(c), - std::forward(gen)); -} - -// c_sample() -// -// Container-based version of the `std::sample()` function to -// randomly sample elements from the container without replacement using a -// `gen()` uniform random number generator and write them to an iterator range. -template -OutputIterator c_sample(const C& c, OutputIterator result, Distance n, - UniformRandomBitGenerator&& gen) { -#if defined(__cpp_lib_sample) && __cpp_lib_sample >= 201603L - return std::sample(container_algorithm_internal::c_begin(c), - container_algorithm_internal::c_end(c), result, n, - std::forward(gen)); -#else - // Fall back to a stable selection-sampling implementation. - auto first = container_algorithm_internal::c_begin(c); - Distance unsampled_elements = c_distance(c); - n = (std::min)(n, unsampled_elements); - for (; n != 0; ++first) { - Distance r = - std::uniform_int_distribution(0, --unsampled_elements)(gen); - if (r < n) { - *result++ = *first; - --n; - } - } - return result; -#endif -} - -//------------------------------------------------------------------------------ -// Partition functions -//------------------------------------------------------------------------------ - -// c_is_partitioned() -// -// Container-based version of the `std::is_partitioned()` function -// to test whether all elements in the container for which `pred` returns `true` -// precede those for which `pred` is `false`. -template -bool c_is_partitioned(const C& c, Pred&& pred) { - return std::is_partitioned(container_algorithm_internal::c_begin(c), - container_algorithm_internal::c_end(c), - std::forward(pred)); -} - -// c_partition() -// -// Container-based version of the `std::partition()` function -// to rearrange all elements in a container in such a way that all elements for -// which `pred` returns `true` precede all those for which it returns `false`, -// returning an iterator to the first element of the second group. -template -container_algorithm_internal::ContainerIter c_partition(C& c, Pred&& pred) { - return std::partition(container_algorithm_internal::c_begin(c), - container_algorithm_internal::c_end(c), - std::forward(pred)); -} - -// c_stable_partition() -// -// Container-based version of the `std::stable_partition()` function -// to rearrange all elements in a container in such a way that all elements for -// which `pred` returns `true` precede all those for which it returns `false`, -// preserving the relative ordering between the two groups. The function returns -// an iterator to the first element of the second group. -template -container_algorithm_internal::ContainerIter c_stable_partition(C& c, - Pred&& pred) { - return std::stable_partition(container_algorithm_internal::c_begin(c), - container_algorithm_internal::c_end(c), - std::forward(pred)); -} - -// c_partition_copy() -// -// Container-based version of the `std::partition_copy()` function -// to partition a container's elements and return them into two iterators: one -// for which `pred` returns `true`, and one for which `pred` returns `false.` - -template -std::pair c_partition_copy( - const C& c, OutputIterator1 out_true, OutputIterator2 out_false, - Pred&& pred) { - return std::partition_copy(container_algorithm_internal::c_begin(c), - container_algorithm_internal::c_end(c), out_true, - out_false, std::forward(pred)); -} - -// c_partition_point() -// -// Container-based version of the `std::partition_point()` function -// to return the first element of an already partitioned container for which -// the given `pred` is not `true`. -template -container_algorithm_internal::ContainerIter c_partition_point(C& c, - Pred&& pred) { - return std::partition_point(container_algorithm_internal::c_begin(c), - container_algorithm_internal::c_end(c), - std::forward(pred)); -} - -//------------------------------------------------------------------------------ -// Sorting functions -//------------------------------------------------------------------------------ - -// c_sort() -// -// Container-based version of the `std::sort()` function -// to sort elements in ascending order of their values. -template -void c_sort(C& c) { - std::sort(container_algorithm_internal::c_begin(c), - container_algorithm_internal::c_end(c)); -} - -// Overload of c_sort() for performing a `comp` comparison other than the -// default `operator<`. -template -void c_sort(C& c, LessThan&& comp) { - std::sort(container_algorithm_internal::c_begin(c), - container_algorithm_internal::c_end(c), - std::forward(comp)); -} - -// c_stable_sort() -// -// Container-based version of the `std::stable_sort()` function -// to sort elements in ascending order of their values, preserving the order -// of equivalents. -template -void c_stable_sort(C& c) { - std::stable_sort(container_algorithm_internal::c_begin(c), - container_algorithm_internal::c_end(c)); -} - -// Overload of c_stable_sort() for performing a `comp` comparison other than the -// default `operator<`. -template -void c_stable_sort(C& c, LessThan&& comp) { - std::stable_sort(container_algorithm_internal::c_begin(c), - container_algorithm_internal::c_end(c), - std::forward(comp)); -} - -// c_is_sorted() -// -// Container-based version of the `std::is_sorted()` function -// to evaluate whether the given container is sorted in ascending order. -template -bool c_is_sorted(const C& c) { - return std::is_sorted(container_algorithm_internal::c_begin(c), - container_algorithm_internal::c_end(c)); -} - -// c_is_sorted() overload for performing a `comp` comparison other than the -// default `operator<`. -template -bool c_is_sorted(const C& c, LessThan&& comp) { - return std::is_sorted(container_algorithm_internal::c_begin(c), - container_algorithm_internal::c_end(c), - std::forward(comp)); -} - -// c_partial_sort() -// -// Container-based version of the `std::partial_sort()` function -// to rearrange elements within a container such that elements before `middle` -// are sorted in ascending order. -template -void c_partial_sort( - RandomAccessContainer& sequence, - container_algorithm_internal::ContainerIter middle) { - std::partial_sort(container_algorithm_internal::c_begin(sequence), middle, - container_algorithm_internal::c_end(sequence)); -} - -// Overload of c_partial_sort() for performing a `comp` comparison other than -// the default `operator<`. -template -void c_partial_sort( - RandomAccessContainer& sequence, - container_algorithm_internal::ContainerIter middle, - LessThan&& comp) { - std::partial_sort(container_algorithm_internal::c_begin(sequence), middle, - container_algorithm_internal::c_end(sequence), - std::forward(comp)); -} - -// c_partial_sort_copy() -// -// Container-based version of the `std::partial_sort_copy()` -// function to sort the elements in the given range `result` within the larger -// `sequence` in ascending order (and using `result` as the output parameter). -// At most min(result.last - result.first, sequence.last - sequence.first) -// elements from the sequence will be stored in the result. -template -container_algorithm_internal::ContainerIter -c_partial_sort_copy(const C& sequence, RandomAccessContainer& result) { - return std::partial_sort_copy(container_algorithm_internal::c_begin(sequence), - container_algorithm_internal::c_end(sequence), - container_algorithm_internal::c_begin(result), - container_algorithm_internal::c_end(result)); -} - -// Overload of c_partial_sort_copy() for performing a `comp` comparison other -// than the default `operator<`. -template -container_algorithm_internal::ContainerIter -c_partial_sort_copy(const C& sequence, RandomAccessContainer& result, - LessThan&& comp) { - return std::partial_sort_copy(container_algorithm_internal::c_begin(sequence), - container_algorithm_internal::c_end(sequence), - container_algorithm_internal::c_begin(result), - container_algorithm_internal::c_end(result), - std::forward(comp)); -} - -// c_is_sorted_until() -// -// Container-based version of the `std::is_sorted_until()` function -// to return the first element within a container that is not sorted in -// ascending order as an iterator. -template -container_algorithm_internal::ContainerIter c_is_sorted_until(C& c) { - return std::is_sorted_until(container_algorithm_internal::c_begin(c), - container_algorithm_internal::c_end(c)); -} - -// Overload of c_is_sorted_until() for performing a `comp` comparison other than -// the default `operator<`. -template -container_algorithm_internal::ContainerIter c_is_sorted_until( - C& c, LessThan&& comp) { - return std::is_sorted_until(container_algorithm_internal::c_begin(c), - container_algorithm_internal::c_end(c), - std::forward(comp)); -} - -// c_nth_element() -// -// Container-based version of the `std::nth_element()` function -// to rearrange the elements within a container such that the `nth` element -// would be in that position in an ordered sequence; other elements may be in -// any order, except that all preceding `nth` will be less than that element, -// and all following `nth` will be greater than that element. -template -void c_nth_element( - RandomAccessContainer& sequence, - container_algorithm_internal::ContainerIter nth) { - std::nth_element(container_algorithm_internal::c_begin(sequence), nth, - container_algorithm_internal::c_end(sequence)); -} - -// Overload of c_nth_element() for performing a `comp` comparison other than -// the default `operator<`. -template -void c_nth_element( - RandomAccessContainer& sequence, - container_algorithm_internal::ContainerIter nth, - LessThan&& comp) { - std::nth_element(container_algorithm_internal::c_begin(sequence), nth, - container_algorithm_internal::c_end(sequence), - std::forward(comp)); -} - -//------------------------------------------------------------------------------ -// Binary Search -//------------------------------------------------------------------------------ - -// c_lower_bound() -// -// Container-based version of the `std::lower_bound()` function -// to return an iterator pointing to the first element in a sorted container -// which does not compare less than `value`. -template -container_algorithm_internal::ContainerIter c_lower_bound( - Sequence& sequence, const T& value) { - return std::lower_bound(container_algorithm_internal::c_begin(sequence), - container_algorithm_internal::c_end(sequence), value); -} - -// Overload of c_lower_bound() for performing a `comp` comparison other than -// the default `operator<`. -template -container_algorithm_internal::ContainerIter c_lower_bound( - Sequence& sequence, const T& value, LessThan&& comp) { - return std::lower_bound(container_algorithm_internal::c_begin(sequence), - container_algorithm_internal::c_end(sequence), value, - std::forward(comp)); -} - -// c_upper_bound() -// -// Container-based version of the `std::upper_bound()` function -// to return an iterator pointing to the first element in a sorted container -// which is greater than `value`. -template -container_algorithm_internal::ContainerIter c_upper_bound( - Sequence& sequence, const T& value) { - return std::upper_bound(container_algorithm_internal::c_begin(sequence), - container_algorithm_internal::c_end(sequence), value); -} - -// Overload of c_upper_bound() for performing a `comp` comparison other than -// the default `operator<`. -template -container_algorithm_internal::ContainerIter c_upper_bound( - Sequence& sequence, const T& value, LessThan&& comp) { - return std::upper_bound(container_algorithm_internal::c_begin(sequence), - container_algorithm_internal::c_end(sequence), value, - std::forward(comp)); -} - -// c_equal_range() -// -// Container-based version of the `std::equal_range()` function -// to return an iterator pair pointing to the first and last elements in a -// sorted container which compare equal to `value`. -template -container_algorithm_internal::ContainerIterPairType -c_equal_range(Sequence& sequence, const T& value) { - return std::equal_range(container_algorithm_internal::c_begin(sequence), - container_algorithm_internal::c_end(sequence), value); -} - -// Overload of c_equal_range() for performing a `comp` comparison other than -// the default `operator<`. -template -container_algorithm_internal::ContainerIterPairType -c_equal_range(Sequence& sequence, const T& value, LessThan&& comp) { - return std::equal_range(container_algorithm_internal::c_begin(sequence), - container_algorithm_internal::c_end(sequence), value, - std::forward(comp)); -} - -// c_binary_search() -// -// Container-based version of the `std::binary_search()` function -// to test if any element in the sorted container contains a value equivalent to -// 'value'. -template -bool c_binary_search(const Sequence& sequence, const T& value) { - return std::binary_search(container_algorithm_internal::c_begin(sequence), - container_algorithm_internal::c_end(sequence), - value); -} - -// Overload of c_binary_search() for performing a `comp` comparison other than -// the default `operator<`. -template -bool c_binary_search(const Sequence& sequence, const T& value, - LessThan&& comp) { - return std::binary_search(container_algorithm_internal::c_begin(sequence), - container_algorithm_internal::c_end(sequence), - value, std::forward(comp)); -} - -//------------------------------------------------------------------------------ -// Merge functions -//------------------------------------------------------------------------------ - -// c_merge() -// -// Container-based version of the `std::merge()` function -// to merge two sorted containers into a single sorted iterator. -template -OutputIterator c_merge(const C1& c1, const C2& c2, OutputIterator result) { - return std::merge(container_algorithm_internal::c_begin(c1), - container_algorithm_internal::c_end(c1), - container_algorithm_internal::c_begin(c2), - container_algorithm_internal::c_end(c2), result); -} - -// Overload of c_merge() for performing a `comp` comparison other than -// the default `operator<`. -template -OutputIterator c_merge(const C1& c1, const C2& c2, OutputIterator result, - LessThan&& comp) { - return std::merge(container_algorithm_internal::c_begin(c1), - container_algorithm_internal::c_end(c1), - container_algorithm_internal::c_begin(c2), - container_algorithm_internal::c_end(c2), result, - std::forward(comp)); -} - -// c_inplace_merge() -// -// Container-based version of the `std::inplace_merge()` function -// to merge a supplied iterator `middle` into a container. -template -void c_inplace_merge(C& c, - container_algorithm_internal::ContainerIter middle) { - std::inplace_merge(container_algorithm_internal::c_begin(c), middle, - container_algorithm_internal::c_end(c)); -} - -// Overload of c_inplace_merge() for performing a merge using a `comp` other -// than `operator<`. -template -void c_inplace_merge(C& c, - container_algorithm_internal::ContainerIter middle, - LessThan&& comp) { - std::inplace_merge(container_algorithm_internal::c_begin(c), middle, - container_algorithm_internal::c_end(c), - std::forward(comp)); -} - -// c_includes() -// -// Container-based version of the `std::includes()` function -// to test whether a sorted container `c1` entirely contains another sorted -// container `c2`. -template -bool c_includes(const C1& c1, const C2& c2) { - return std::includes(container_algorithm_internal::c_begin(c1), - container_algorithm_internal::c_end(c1), - container_algorithm_internal::c_begin(c2), - container_algorithm_internal::c_end(c2)); -} - -// Overload of c_includes() for performing a merge using a `comp` other than -// `operator<`. -template -bool c_includes(const C1& c1, const C2& c2, LessThan&& comp) { - return std::includes(container_algorithm_internal::c_begin(c1), - container_algorithm_internal::c_end(c1), - container_algorithm_internal::c_begin(c2), - container_algorithm_internal::c_end(c2), - std::forward(comp)); -} - -// c_set_union() -// -// Container-based version of the `std::set_union()` function -// to return an iterator containing the union of two containers; duplicate -// values are not copied into the output. -template ::value, - void>::type, - typename = typename std::enable_if< - !container_algorithm_internal::IsUnorderedContainer::value, - void>::type> -OutputIterator c_set_union(const C1& c1, const C2& c2, OutputIterator output) { - return std::set_union(container_algorithm_internal::c_begin(c1), - container_algorithm_internal::c_end(c1), - container_algorithm_internal::c_begin(c2), - container_algorithm_internal::c_end(c2), output); -} - -// Overload of c_set_union() for performing a merge using a `comp` other than -// `operator<`. -template ::value, - void>::type, - typename = typename std::enable_if< - !container_algorithm_internal::IsUnorderedContainer::value, - void>::type> -OutputIterator c_set_union(const C1& c1, const C2& c2, OutputIterator output, - LessThan&& comp) { - return std::set_union(container_algorithm_internal::c_begin(c1), - container_algorithm_internal::c_end(c1), - container_algorithm_internal::c_begin(c2), - container_algorithm_internal::c_end(c2), output, - std::forward(comp)); -} - -// c_set_intersection() -// -// Container-based version of the `std::set_intersection()` function -// to return an iterator containing the intersection of two sorted containers. -template ::value, - void>::type, - typename = typename std::enable_if< - !container_algorithm_internal::IsUnorderedContainer::value, - void>::type> -OutputIterator c_set_intersection(const C1& c1, const C2& c2, - OutputIterator output) { - // In debug builds, ensure that both containers are sorted with respect to the - // default comparator. std::set_intersection requires the containers be sorted - // using operator<. - assert(absl::c_is_sorted(c1)); - assert(absl::c_is_sorted(c2)); - return std::set_intersection(container_algorithm_internal::c_begin(c1), - container_algorithm_internal::c_end(c1), - container_algorithm_internal::c_begin(c2), - container_algorithm_internal::c_end(c2), output); -} - -// Overload of c_set_intersection() for performing a merge using a `comp` other -// than `operator<`. -template ::value, - void>::type, - typename = typename std::enable_if< - !container_algorithm_internal::IsUnorderedContainer::value, - void>::type> -OutputIterator c_set_intersection(const C1& c1, const C2& c2, - OutputIterator output, LessThan&& comp) { - // In debug builds, ensure that both containers are sorted with respect to the - // default comparator. std::set_intersection requires the containers be sorted - // using the same comparator. - assert(absl::c_is_sorted(c1, comp)); - assert(absl::c_is_sorted(c2, comp)); - return std::set_intersection(container_algorithm_internal::c_begin(c1), - container_algorithm_internal::c_end(c1), - container_algorithm_internal::c_begin(c2), - container_algorithm_internal::c_end(c2), output, - std::forward(comp)); -} - -// c_set_difference() -// -// Container-based version of the `std::set_difference()` function -// to return an iterator containing elements present in the first container but -// not in the second. -template ::value, - void>::type, - typename = typename std::enable_if< - !container_algorithm_internal::IsUnorderedContainer::value, - void>::type> -OutputIterator c_set_difference(const C1& c1, const C2& c2, - OutputIterator output) { - return std::set_difference(container_algorithm_internal::c_begin(c1), - container_algorithm_internal::c_end(c1), - container_algorithm_internal::c_begin(c2), - container_algorithm_internal::c_end(c2), output); -} - -// Overload of c_set_difference() for performing a merge using a `comp` other -// than `operator<`. -template ::value, - void>::type, - typename = typename std::enable_if< - !container_algorithm_internal::IsUnorderedContainer::value, - void>::type> -OutputIterator c_set_difference(const C1& c1, const C2& c2, - OutputIterator output, LessThan&& comp) { - return std::set_difference(container_algorithm_internal::c_begin(c1), - container_algorithm_internal::c_end(c1), - container_algorithm_internal::c_begin(c2), - container_algorithm_internal::c_end(c2), output, - std::forward(comp)); -} - -// c_set_symmetric_difference() -// -// Container-based version of the `std::set_symmetric_difference()` -// function to return an iterator containing elements present in either one -// container or the other, but not both. -template ::value, - void>::type, - typename = typename std::enable_if< - !container_algorithm_internal::IsUnorderedContainer::value, - void>::type> -OutputIterator c_set_symmetric_difference(const C1& c1, const C2& c2, - OutputIterator output) { - return std::set_symmetric_difference( - container_algorithm_internal::c_begin(c1), - container_algorithm_internal::c_end(c1), - container_algorithm_internal::c_begin(c2), - container_algorithm_internal::c_end(c2), output); -} - -// Overload of c_set_symmetric_difference() for performing a merge using a -// `comp` other than `operator<`. -template ::value, - void>::type, - typename = typename std::enable_if< - !container_algorithm_internal::IsUnorderedContainer::value, - void>::type> -OutputIterator c_set_symmetric_difference(const C1& c1, const C2& c2, - OutputIterator output, - LessThan&& comp) { - return std::set_symmetric_difference( - container_algorithm_internal::c_begin(c1), - container_algorithm_internal::c_end(c1), - container_algorithm_internal::c_begin(c2), - container_algorithm_internal::c_end(c2), output, - std::forward(comp)); -} - -//------------------------------------------------------------------------------ -// Heap functions -//------------------------------------------------------------------------------ - -// c_push_heap() -// -// Container-based version of the `std::push_heap()` function -// to push a value onto a container heap. -template -void c_push_heap(RandomAccessContainer& sequence) { - std::push_heap(container_algorithm_internal::c_begin(sequence), - container_algorithm_internal::c_end(sequence)); -} - -// Overload of c_push_heap() for performing a push operation on a heap using a -// `comp` other than `operator<`. -template -void c_push_heap(RandomAccessContainer& sequence, LessThan&& comp) { - std::push_heap(container_algorithm_internal::c_begin(sequence), - container_algorithm_internal::c_end(sequence), - std::forward(comp)); -} - -// c_pop_heap() -// -// Container-based version of the `std::pop_heap()` function -// to pop a value from a heap container. -template -void c_pop_heap(RandomAccessContainer& sequence) { - std::pop_heap(container_algorithm_internal::c_begin(sequence), - container_algorithm_internal::c_end(sequence)); -} - -// Overload of c_pop_heap() for performing a pop operation on a heap using a -// `comp` other than `operator<`. -template -void c_pop_heap(RandomAccessContainer& sequence, LessThan&& comp) { - std::pop_heap(container_algorithm_internal::c_begin(sequence), - container_algorithm_internal::c_end(sequence), - std::forward(comp)); -} - -// c_make_heap() -// -// Container-based version of the `std::make_heap()` function -// to make a container a heap. -template -void c_make_heap(RandomAccessContainer& sequence) { - std::make_heap(container_algorithm_internal::c_begin(sequence), - container_algorithm_internal::c_end(sequence)); -} - -// Overload of c_make_heap() for performing heap comparisons using a -// `comp` other than `operator<` -template -void c_make_heap(RandomAccessContainer& sequence, LessThan&& comp) { - std::make_heap(container_algorithm_internal::c_begin(sequence), - container_algorithm_internal::c_end(sequence), - std::forward(comp)); -} - -// c_sort_heap() -// -// Container-based version of the `std::sort_heap()` function -// to sort a heap into ascending order (after which it is no longer a heap). -template -void c_sort_heap(RandomAccessContainer& sequence) { - std::sort_heap(container_algorithm_internal::c_begin(sequence), - container_algorithm_internal::c_end(sequence)); -} - -// Overload of c_sort_heap() for performing heap comparisons using a -// `comp` other than `operator<` -template -void c_sort_heap(RandomAccessContainer& sequence, LessThan&& comp) { - std::sort_heap(container_algorithm_internal::c_begin(sequence), - container_algorithm_internal::c_end(sequence), - std::forward(comp)); -} - -// c_is_heap() -// -// Container-based version of the `std::is_heap()` function -// to check whether the given container is a heap. -template -bool c_is_heap(const RandomAccessContainer& sequence) { - return std::is_heap(container_algorithm_internal::c_begin(sequence), - container_algorithm_internal::c_end(sequence)); -} - -// Overload of c_is_heap() for performing heap comparisons using a -// `comp` other than `operator<` -template -bool c_is_heap(const RandomAccessContainer& sequence, LessThan&& comp) { - return std::is_heap(container_algorithm_internal::c_begin(sequence), - container_algorithm_internal::c_end(sequence), - std::forward(comp)); -} - -// c_is_heap_until() -// -// Container-based version of the `std::is_heap_until()` function -// to find the first element in a given container which is not in heap order. -template -container_algorithm_internal::ContainerIter -c_is_heap_until(RandomAccessContainer& sequence) { - return std::is_heap_until(container_algorithm_internal::c_begin(sequence), - container_algorithm_internal::c_end(sequence)); -} - -// Overload of c_is_heap_until() for performing heap comparisons using a -// `comp` other than `operator<` -template -container_algorithm_internal::ContainerIter -c_is_heap_until(RandomAccessContainer& sequence, LessThan&& comp) { - return std::is_heap_until(container_algorithm_internal::c_begin(sequence), - container_algorithm_internal::c_end(sequence), - std::forward(comp)); -} - -//------------------------------------------------------------------------------ -// Min/max -//------------------------------------------------------------------------------ - -// c_min_element() -// -// Container-based version of the `std::min_element()` function -// to return an iterator pointing to the element with the smallest value, using -// `operator<` to make the comparisons. -template -container_algorithm_internal::ContainerIter c_min_element( - Sequence& sequence) { - return std::min_element(container_algorithm_internal::c_begin(sequence), - container_algorithm_internal::c_end(sequence)); -} - -// Overload of c_min_element() for performing a `comp` comparison other than -// `operator<`. -template -container_algorithm_internal::ContainerIter c_min_element( - Sequence& sequence, LessThan&& comp) { - return std::min_element(container_algorithm_internal::c_begin(sequence), - container_algorithm_internal::c_end(sequence), - std::forward(comp)); -} - -// c_max_element() -// -// Container-based version of the `std::max_element()` function -// to return an iterator pointing to the element with the largest value, using -// `operator<` to make the comparisons. -template -container_algorithm_internal::ContainerIter c_max_element( - Sequence& sequence) { - return std::max_element(container_algorithm_internal::c_begin(sequence), - container_algorithm_internal::c_end(sequence)); -} - -// Overload of c_max_element() for performing a `comp` comparison other than -// `operator<`. -template -container_algorithm_internal::ContainerIter c_max_element( - Sequence& sequence, LessThan&& comp) { - return std::max_element(container_algorithm_internal::c_begin(sequence), - container_algorithm_internal::c_end(sequence), - std::forward(comp)); -} - -// c_minmax_element() -// -// Container-based version of the `std::minmax_element()` function -// to return a pair of iterators pointing to the elements containing the -// smallest and largest values, respectively, using `operator<` to make the -// comparisons. -template -container_algorithm_internal::ContainerIterPairType c_minmax_element( - C& c) { - return std::minmax_element(container_algorithm_internal::c_begin(c), - container_algorithm_internal::c_end(c)); -} - -// Overload of c_minmax_element() for performing `comp` comparisons other than -// `operator<`. -template -container_algorithm_internal::ContainerIterPairType c_minmax_element( - C& c, LessThan&& comp) { - return std::minmax_element(container_algorithm_internal::c_begin(c), - container_algorithm_internal::c_end(c), - std::forward(comp)); -} - -//------------------------------------------------------------------------------ -// Lexicographical Comparisons -//------------------------------------------------------------------------------ - -// c_lexicographical_compare() -// -// Container-based version of the `std::lexicographical_compare()` -// function to lexicographically compare (e.g. sort words alphabetically) two -// container sequences. The comparison is performed using `operator<`. Note -// that capital letters ("A-Z") have ASCII values less than lowercase letters -// ("a-z"). -template -bool c_lexicographical_compare(const Sequence1& sequence1, - const Sequence2& sequence2) { - return std::lexicographical_compare( - container_algorithm_internal::c_begin(sequence1), - container_algorithm_internal::c_end(sequence1), - container_algorithm_internal::c_begin(sequence2), - container_algorithm_internal::c_end(sequence2)); -} - -// Overload of c_lexicographical_compare() for performing a lexicographical -// comparison using a `comp` operator instead of `operator<`. -template -bool c_lexicographical_compare(const Sequence1& sequence1, - const Sequence2& sequence2, LessThan&& comp) { - return std::lexicographical_compare( - container_algorithm_internal::c_begin(sequence1), - container_algorithm_internal::c_end(sequence1), - container_algorithm_internal::c_begin(sequence2), - container_algorithm_internal::c_end(sequence2), - std::forward(comp)); -} - -// c_next_permutation() -// -// Container-based version of the `std::next_permutation()` function -// to rearrange a container's elements into the next lexicographically greater -// permutation. -template -bool c_next_permutation(C& c) { - return std::next_permutation(container_algorithm_internal::c_begin(c), - container_algorithm_internal::c_end(c)); -} - -// Overload of c_next_permutation() for performing a lexicographical -// comparison using a `comp` operator instead of `operator<`. -template -bool c_next_permutation(C& c, LessThan&& comp) { - return std::next_permutation(container_algorithm_internal::c_begin(c), - container_algorithm_internal::c_end(c), - std::forward(comp)); -} - -// c_prev_permutation() -// -// Container-based version of the `std::prev_permutation()` function -// to rearrange a container's elements into the next lexicographically lesser -// permutation. -template -bool c_prev_permutation(C& c) { - return std::prev_permutation(container_algorithm_internal::c_begin(c), - container_algorithm_internal::c_end(c)); -} - -// Overload of c_prev_permutation() for performing a lexicographical -// comparison using a `comp` operator instead of `operator<`. -template -bool c_prev_permutation(C& c, LessThan&& comp) { - return std::prev_permutation(container_algorithm_internal::c_begin(c), - container_algorithm_internal::c_end(c), - std::forward(comp)); -} - -//------------------------------------------------------------------------------ -// algorithms -//------------------------------------------------------------------------------ - -// c_iota() -// -// Container-based version of the `std::iota()` function -// to compute successive values of `value`, as if incremented with `++value` -// after each element is written, and write them to the container. -template -void c_iota(Sequence& sequence, const T& value) { - std::iota(container_algorithm_internal::c_begin(sequence), - container_algorithm_internal::c_end(sequence), value); -} - -// c_accumulate() -// -// Container-based version of the `std::accumulate()` function -// to accumulate the element values of a container to `init` and return that -// accumulation by value. -// -// Note: Due to a language technicality this function has return type -// absl::decay_t. As a user of this function you can casually read -// this as "returns T by value" and assume it does the right thing. -template -decay_t c_accumulate(const Sequence& sequence, T&& init) { - return std::accumulate(container_algorithm_internal::c_begin(sequence), - container_algorithm_internal::c_end(sequence), - std::forward(init)); -} - -// Overload of c_accumulate() for using a binary operations other than -// addition for computing the accumulation. -template -decay_t c_accumulate(const Sequence& sequence, T&& init, - BinaryOp&& binary_op) { - return std::accumulate(container_algorithm_internal::c_begin(sequence), - container_algorithm_internal::c_end(sequence), - std::forward(init), - std::forward(binary_op)); -} - -// c_inner_product() -// -// Container-based version of the `std::inner_product()` function -// to compute the cumulative inner product of container element pairs. -// -// Note: Due to a language technicality this function has return type -// absl::decay_t. As a user of this function you can casually read -// this as "returns T by value" and assume it does the right thing. -template -decay_t c_inner_product(const Sequence1& factors1, const Sequence2& factors2, - T&& sum) { - return std::inner_product(container_algorithm_internal::c_begin(factors1), - container_algorithm_internal::c_end(factors1), - container_algorithm_internal::c_begin(factors2), - std::forward(sum)); -} - -// Overload of c_inner_product() for using binary operations other than -// `operator+` (for computing the accumulation) and `operator*` (for computing -// the product between the two container's element pair). -template -decay_t c_inner_product(const Sequence1& factors1, const Sequence2& factors2, - T&& sum, BinaryOp1&& op1, BinaryOp2&& op2) { - return std::inner_product(container_algorithm_internal::c_begin(factors1), - container_algorithm_internal::c_end(factors1), - container_algorithm_internal::c_begin(factors2), - std::forward(sum), std::forward(op1), - std::forward(op2)); -} - -// c_adjacent_difference() -// -// Container-based version of the `std::adjacent_difference()` -// function to compute the difference between each element and the one preceding -// it and write it to an iterator. -template -OutputIt c_adjacent_difference(const InputSequence& input, - OutputIt output_first) { - return std::adjacent_difference(container_algorithm_internal::c_begin(input), - container_algorithm_internal::c_end(input), - output_first); -} - -// Overload of c_adjacent_difference() for using a binary operation other than -// subtraction to compute the adjacent difference. -template -OutputIt c_adjacent_difference(const InputSequence& input, - OutputIt output_first, BinaryOp&& op) { - return std::adjacent_difference(container_algorithm_internal::c_begin(input), - container_algorithm_internal::c_end(input), - output_first, std::forward(op)); -} - -// c_partial_sum() -// -// Container-based version of the `std::partial_sum()` function -// to compute the partial sum of the elements in a sequence and write them -// to an iterator. The partial sum is the sum of all element values so far in -// the sequence. -template -OutputIt c_partial_sum(const InputSequence& input, OutputIt output_first) { - return std::partial_sum(container_algorithm_internal::c_begin(input), - container_algorithm_internal::c_end(input), - output_first); -} - -// Overload of c_partial_sum() for using a binary operation other than addition -// to compute the "partial sum". -template -OutputIt c_partial_sum(const InputSequence& input, OutputIt output_first, - BinaryOp&& op) { - return std::partial_sum(container_algorithm_internal::c_begin(input), - container_algorithm_internal::c_end(input), - output_first, std::forward(op)); -} - -ABSL_NAMESPACE_END -} // namespace absl - -#endif // ABSL_ALGORITHM_CONTAINER_H_ diff --git a/projects/llm_framework/include/abseil-cpp/absl/base/attributes.h b/projects/llm_framework/include/abseil-cpp/absl/base/attributes.h deleted file mode 100644 index 38086a82..00000000 --- a/projects/llm_framework/include/abseil-cpp/absl/base/attributes.h +++ /dev/null @@ -1,921 +0,0 @@ -// Copyright 2017 The Abseil Authors. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// https://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -// -// This header file defines macros for declaring attributes for functions, -// types, and variables. -// -// These macros are used within Abseil and allow the compiler to optimize, where -// applicable, certain function calls. -// -// Most macros here are exposing GCC or Clang features, and are stubbed out for -// other compilers. -// -// GCC attributes documentation: -// https://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/Function-Attributes.html -// https://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/Variable-Attributes.html -// https://gcc.gnu.org/onlinedocs/gcc-4.7.0/gcc/Type-Attributes.html -// -// Most attributes in this file are already supported by GCC 4.7. However, some -// of them are not supported in older version of Clang. Thus, we check -// `__has_attribute()` first. If the check fails, we check if we are on GCC and -// assume the attribute exists on GCC (which is verified on GCC 4.7). - -#ifndef ABSL_BASE_ATTRIBUTES_H_ -#define ABSL_BASE_ATTRIBUTES_H_ - -#include "absl/base/config.h" - -// ABSL_HAVE_ATTRIBUTE -// -// A function-like feature checking macro that is a wrapper around -// `__has_attribute`, which is defined by GCC 5+ and Clang and evaluates to a -// nonzero constant integer if the attribute is supported or 0 if not. -// -// It evaluates to zero if `__has_attribute` is not defined by the compiler. -// -// GCC: https://gcc.gnu.org/gcc-5/changes.html -// Clang: https://clang.llvm.org/docs/LanguageExtensions.html -#ifdef __has_attribute -#define ABSL_HAVE_ATTRIBUTE(x) __has_attribute(x) -#else -#define ABSL_HAVE_ATTRIBUTE(x) 0 -#endif - -// ABSL_HAVE_CPP_ATTRIBUTE -// -// A function-like feature checking macro that accepts C++11 style attributes. -// It's a wrapper around `__has_cpp_attribute`, defined by ISO C++ SD-6 -// (https://en.cppreference.com/w/cpp/experimental/feature_test). If we don't -// find `__has_cpp_attribute`, will evaluate to 0. -#if defined(__cplusplus) && defined(__has_cpp_attribute) -// NOTE: requiring __cplusplus above should not be necessary, but -// works around https://bugs.llvm.org/show_bug.cgi?id=23435. -#define ABSL_HAVE_CPP_ATTRIBUTE(x) __has_cpp_attribute(x) -#else -#define ABSL_HAVE_CPP_ATTRIBUTE(x) 0 -#endif - -// ----------------------------------------------------------------------------- -// Function Attributes -// ----------------------------------------------------------------------------- -// -// GCC: https://gcc.gnu.org/onlinedocs/gcc/Function-Attributes.html -// Clang: https://clang.llvm.org/docs/AttributeReference.html - -// ABSL_PRINTF_ATTRIBUTE -// ABSL_SCANF_ATTRIBUTE -// -// Tells the compiler to perform `printf` format string checking if the -// compiler supports it; see the 'format' attribute in -// . -// -// Note: As the GCC manual states, "[s]ince non-static C++ methods -// have an implicit 'this' argument, the arguments of such methods -// should be counted from two, not one." -#if ABSL_HAVE_ATTRIBUTE(format) || (defined(__GNUC__) && !defined(__clang__)) -#define ABSL_PRINTF_ATTRIBUTE(string_index, first_to_check) \ - __attribute__((__format__(__printf__, string_index, first_to_check))) -#define ABSL_SCANF_ATTRIBUTE(string_index, first_to_check) \ - __attribute__((__format__(__scanf__, string_index, first_to_check))) -#else -#define ABSL_PRINTF_ATTRIBUTE(string_index, first_to_check) -#define ABSL_SCANF_ATTRIBUTE(string_index, first_to_check) -#endif - -// ABSL_ATTRIBUTE_ALWAYS_INLINE -// ABSL_ATTRIBUTE_NOINLINE -// -// Forces functions to either inline or not inline. Introduced in gcc 3.1. -#if ABSL_HAVE_ATTRIBUTE(always_inline) || \ - (defined(__GNUC__) && !defined(__clang__)) -#define ABSL_ATTRIBUTE_ALWAYS_INLINE __attribute__((always_inline)) -#define ABSL_HAVE_ATTRIBUTE_ALWAYS_INLINE 1 -#else -#define ABSL_ATTRIBUTE_ALWAYS_INLINE -#endif - -#if ABSL_HAVE_ATTRIBUTE(noinline) || (defined(__GNUC__) && !defined(__clang__)) -#define ABSL_ATTRIBUTE_NOINLINE __attribute__((noinline)) -#define ABSL_HAVE_ATTRIBUTE_NOINLINE 1 -#else -#define ABSL_ATTRIBUTE_NOINLINE -#endif - -// ABSL_ATTRIBUTE_NO_TAIL_CALL -// -// Prevents the compiler from optimizing away stack frames for functions which -// end in a call to another function. -#if ABSL_HAVE_ATTRIBUTE(disable_tail_calls) -#define ABSL_HAVE_ATTRIBUTE_NO_TAIL_CALL 1 -#define ABSL_ATTRIBUTE_NO_TAIL_CALL __attribute__((disable_tail_calls)) -#elif defined(__GNUC__) && !defined(__clang__) && !defined(__e2k__) -#define ABSL_HAVE_ATTRIBUTE_NO_TAIL_CALL 1 -#define ABSL_ATTRIBUTE_NO_TAIL_CALL \ - __attribute__((optimize("no-optimize-sibling-calls"))) -#else -#define ABSL_ATTRIBUTE_NO_TAIL_CALL -#define ABSL_HAVE_ATTRIBUTE_NO_TAIL_CALL 0 -#endif - -// ABSL_ATTRIBUTE_WEAK -// -// Tags a function as weak for the purposes of compilation and linking. -// Weak attributes did not work properly in LLVM's Windows backend before -// 9.0.0, so disable them there. See https://bugs.llvm.org/show_bug.cgi?id=37598 -// for further information. -// The MinGW compiler doesn't complain about the weak attribute until the link -// step, presumably because Windows doesn't use ELF binaries. -#if (ABSL_HAVE_ATTRIBUTE(weak) || \ - (defined(__GNUC__) && !defined(__clang__))) && \ - (!defined(_WIN32) || (defined(__clang__) && __clang_major__ >= 9)) && \ - !defined(__MINGW32__) -#undef ABSL_ATTRIBUTE_WEAK -#define ABSL_ATTRIBUTE_WEAK __attribute__((weak)) -#define ABSL_HAVE_ATTRIBUTE_WEAK 1 -#else -#define ABSL_ATTRIBUTE_WEAK -#define ABSL_HAVE_ATTRIBUTE_WEAK 0 -#endif - -// ABSL_ATTRIBUTE_NONNULL -// -// Tells the compiler either (a) that a particular function parameter -// should be a non-null pointer, or (b) that all pointer arguments should -// be non-null. -// -// Note: As the GCC manual states, "[s]ince non-static C++ methods -// have an implicit 'this' argument, the arguments of such methods -// should be counted from two, not one." -// -// Args are indexed starting at 1. -// -// For non-static class member functions, the implicit `this` argument -// is arg 1, and the first explicit argument is arg 2. For static class member -// functions, there is no implicit `this`, and the first explicit argument is -// arg 1. -// -// Example: -// -// /* arg_a cannot be null, but arg_b can */ -// void Function(void* arg_a, void* arg_b) ABSL_ATTRIBUTE_NONNULL(1); -// -// class C { -// /* arg_a cannot be null, but arg_b can */ -// void Method(void* arg_a, void* arg_b) ABSL_ATTRIBUTE_NONNULL(2); -// -// /* arg_a cannot be null, but arg_b can */ -// static void StaticMethod(void* arg_a, void* arg_b) -// ABSL_ATTRIBUTE_NONNULL(1); -// }; -// -// If no arguments are provided, then all pointer arguments should be non-null. -// -// /* No pointer arguments may be null. */ -// void Function(void* arg_a, void* arg_b, int arg_c) ABSL_ATTRIBUTE_NONNULL(); -// -// NOTE: The GCC nonnull attribute actually accepts a list of arguments, but -// ABSL_ATTRIBUTE_NONNULL does not. -#if ABSL_HAVE_ATTRIBUTE(nonnull) || (defined(__GNUC__) && !defined(__clang__)) -#define ABSL_ATTRIBUTE_NONNULL(arg_index) __attribute__((nonnull(arg_index))) -#else -#define ABSL_ATTRIBUTE_NONNULL(...) -#endif - -// ABSL_ATTRIBUTE_NORETURN -// -// Tells the compiler that a given function never returns. -#if ABSL_HAVE_ATTRIBUTE(noreturn) || (defined(__GNUC__) && !defined(__clang__)) -#define ABSL_ATTRIBUTE_NORETURN __attribute__((noreturn)) -#elif defined(_MSC_VER) -#define ABSL_ATTRIBUTE_NORETURN __declspec(noreturn) -#else -#define ABSL_ATTRIBUTE_NORETURN -#endif - -// ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS -// -// Tells the AddressSanitizer (or other memory testing tools) to ignore a given -// function. Useful for cases when a function reads random locations on stack, -// calls _exit from a cloned subprocess, deliberately accesses buffer -// out of bounds or does other scary things with memory. -// NOTE: GCC supports AddressSanitizer(asan) since 4.8. -// https://gcc.gnu.org/gcc-4.8/changes.html -#if defined(ABSL_HAVE_ADDRESS_SANITIZER) && \ - ABSL_HAVE_ATTRIBUTE(no_sanitize_address) -#define ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS __attribute__((no_sanitize_address)) -#elif defined(ABSL_HAVE_ADDRESS_SANITIZER) && defined(_MSC_VER) && \ - _MSC_VER >= 1928 -// https://docs.microsoft.com/en-us/cpp/cpp/no-sanitize-address -#define ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS __declspec(no_sanitize_address) -#elif defined(ABSL_HAVE_HWADDRESS_SANITIZER) && ABSL_HAVE_ATTRIBUTE(no_sanitize) -// HWAddressSanitizer is a sanitizer similar to AddressSanitizer, which uses CPU -// features to detect similar bugs with less CPU and memory overhead. -// NOTE: GCC supports HWAddressSanitizer(hwasan) since 11. -// https://gcc.gnu.org/gcc-11/changes.html -#define ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS \ - __attribute__((no_sanitize("hwaddress"))) -#else -#define ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS -#endif - -// ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY -// -// Tells the MemorySanitizer to relax the handling of a given function. All "Use -// of uninitialized value" warnings from such functions will be suppressed, and -// all values loaded from memory will be considered fully initialized. This -// attribute is similar to the ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS attribute -// above, but deals with initialized-ness rather than addressability issues. -// NOTE: MemorySanitizer(msan) is supported by Clang but not GCC. -#if ABSL_HAVE_ATTRIBUTE(no_sanitize_memory) -#define ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY __attribute__((no_sanitize_memory)) -#else -#define ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY -#endif - -// ABSL_ATTRIBUTE_NO_SANITIZE_THREAD -// -// Tells the ThreadSanitizer to not instrument a given function. -// NOTE: GCC supports ThreadSanitizer(tsan) since 4.8. -// https://gcc.gnu.org/gcc-4.8/changes.html -#if ABSL_HAVE_ATTRIBUTE(no_sanitize_thread) -#define ABSL_ATTRIBUTE_NO_SANITIZE_THREAD __attribute__((no_sanitize_thread)) -#else -#define ABSL_ATTRIBUTE_NO_SANITIZE_THREAD -#endif - -// ABSL_ATTRIBUTE_NO_SANITIZE_UNDEFINED -// -// Tells the UndefinedSanitizer to ignore a given function. Useful for cases -// where certain behavior (eg. division by zero) is being used intentionally. -// NOTE: GCC supports UndefinedBehaviorSanitizer(ubsan) since 4.9. -// https://gcc.gnu.org/gcc-4.9/changes.html -#if ABSL_HAVE_ATTRIBUTE(no_sanitize_undefined) -#define ABSL_ATTRIBUTE_NO_SANITIZE_UNDEFINED \ - __attribute__((no_sanitize_undefined)) -#elif ABSL_HAVE_ATTRIBUTE(no_sanitize) -#define ABSL_ATTRIBUTE_NO_SANITIZE_UNDEFINED \ - __attribute__((no_sanitize("undefined"))) -#else -#define ABSL_ATTRIBUTE_NO_SANITIZE_UNDEFINED -#endif - -// ABSL_ATTRIBUTE_NO_SANITIZE_CFI -// -// Tells the ControlFlowIntegrity sanitizer to not instrument a given function. -// See https://clang.llvm.org/docs/ControlFlowIntegrity.html for details. -#if ABSL_HAVE_ATTRIBUTE(no_sanitize) && defined(__llvm__) -#define ABSL_ATTRIBUTE_NO_SANITIZE_CFI __attribute__((no_sanitize("cfi"))) -#else -#define ABSL_ATTRIBUTE_NO_SANITIZE_CFI -#endif - -// ABSL_ATTRIBUTE_NO_SANITIZE_SAFESTACK -// -// Tells the SafeStack to not instrument a given function. -// See https://clang.llvm.org/docs/SafeStack.html for details. -#if ABSL_HAVE_ATTRIBUTE(no_sanitize) -#define ABSL_ATTRIBUTE_NO_SANITIZE_SAFESTACK \ - __attribute__((no_sanitize("safe-stack"))) -#else -#define ABSL_ATTRIBUTE_NO_SANITIZE_SAFESTACK -#endif - -// ABSL_ATTRIBUTE_RETURNS_NONNULL -// -// Tells the compiler that a particular function never returns a null pointer. -#if ABSL_HAVE_ATTRIBUTE(returns_nonnull) -#define ABSL_ATTRIBUTE_RETURNS_NONNULL __attribute__((returns_nonnull)) -#else -#define ABSL_ATTRIBUTE_RETURNS_NONNULL -#endif - -// ABSL_HAVE_ATTRIBUTE_SECTION -// -// Indicates whether labeled sections are supported. Weak symbol support is -// a prerequisite. Labeled sections are not supported on Darwin/iOS. -#ifdef ABSL_HAVE_ATTRIBUTE_SECTION -#error ABSL_HAVE_ATTRIBUTE_SECTION cannot be directly set -#elif (ABSL_HAVE_ATTRIBUTE(section) || \ - (defined(__GNUC__) && !defined(__clang__))) && \ - !defined(__APPLE__) && ABSL_HAVE_ATTRIBUTE_WEAK -#define ABSL_HAVE_ATTRIBUTE_SECTION 1 - -// ABSL_ATTRIBUTE_SECTION -// -// Tells the compiler/linker to put a given function into a section and define -// `__start_ ## name` and `__stop_ ## name` symbols to bracket the section. -// This functionality is supported by GNU linker. Any function annotated with -// `ABSL_ATTRIBUTE_SECTION` must not be inlined, or it will be placed into -// whatever section its caller is placed into. -// -#ifndef ABSL_ATTRIBUTE_SECTION -#define ABSL_ATTRIBUTE_SECTION(name) \ - __attribute__((section(#name))) __attribute__((noinline)) -#endif - -// ABSL_ATTRIBUTE_SECTION_VARIABLE -// -// Tells the compiler/linker to put a given variable into a section and define -// `__start_ ## name` and `__stop_ ## name` symbols to bracket the section. -// This functionality is supported by GNU linker. -#ifndef ABSL_ATTRIBUTE_SECTION_VARIABLE -#ifdef _AIX -// __attribute__((section(#name))) on AIX is achieved by using the `.csect` -// psudo op which includes an additional integer as part of its syntax indcating -// alignment. If data fall under different alignments then you might get a -// compilation error indicating a `Section type conflict`. -#define ABSL_ATTRIBUTE_SECTION_VARIABLE(name) -#else -#define ABSL_ATTRIBUTE_SECTION_VARIABLE(name) __attribute__((section(#name))) -#endif -#endif - -// ABSL_DECLARE_ATTRIBUTE_SECTION_VARS -// -// A weak section declaration to be used as a global declaration -// for ABSL_ATTRIBUTE_SECTION_START|STOP(name) to compile and link -// even without functions with ABSL_ATTRIBUTE_SECTION(name). -// ABSL_DEFINE_ATTRIBUTE_SECTION should be in the exactly one file; it's -// a no-op on ELF but not on Mach-O. -// -#ifndef ABSL_DECLARE_ATTRIBUTE_SECTION_VARS -#define ABSL_DECLARE_ATTRIBUTE_SECTION_VARS(name) \ - extern char __start_##name[] ABSL_ATTRIBUTE_WEAK; \ - extern char __stop_##name[] ABSL_ATTRIBUTE_WEAK -#endif -#ifndef ABSL_DEFINE_ATTRIBUTE_SECTION_VARS -#define ABSL_INIT_ATTRIBUTE_SECTION_VARS(name) -#define ABSL_DEFINE_ATTRIBUTE_SECTION_VARS(name) -#endif - -// ABSL_ATTRIBUTE_SECTION_START -// -// Returns `void*` pointers to start/end of a section of code with -// functions having ABSL_ATTRIBUTE_SECTION(name). -// Returns 0 if no such functions exist. -// One must ABSL_DECLARE_ATTRIBUTE_SECTION_VARS(name) for this to compile and -// link. -// -#define ABSL_ATTRIBUTE_SECTION_START(name) \ - (reinterpret_cast(__start_##name)) -#define ABSL_ATTRIBUTE_SECTION_STOP(name) \ - (reinterpret_cast(__stop_##name)) - -#else // !ABSL_HAVE_ATTRIBUTE_SECTION - -#define ABSL_HAVE_ATTRIBUTE_SECTION 0 - -// provide dummy definitions -#define ABSL_ATTRIBUTE_SECTION(name) -#define ABSL_ATTRIBUTE_SECTION_VARIABLE(name) -#define ABSL_INIT_ATTRIBUTE_SECTION_VARS(name) -#define ABSL_DEFINE_ATTRIBUTE_SECTION_VARS(name) -#define ABSL_DECLARE_ATTRIBUTE_SECTION_VARS(name) -#define ABSL_ATTRIBUTE_SECTION_START(name) (reinterpret_cast(0)) -#define ABSL_ATTRIBUTE_SECTION_STOP(name) (reinterpret_cast(0)) - -#endif // ABSL_ATTRIBUTE_SECTION - -// ABSL_ATTRIBUTE_STACK_ALIGN_FOR_OLD_LIBC -// -// Support for aligning the stack on 32-bit x86. -#if ABSL_HAVE_ATTRIBUTE(force_align_arg_pointer) || \ - (defined(__GNUC__) && !defined(__clang__)) -#if defined(__i386__) -#define ABSL_ATTRIBUTE_STACK_ALIGN_FOR_OLD_LIBC \ - __attribute__((force_align_arg_pointer)) -#define ABSL_REQUIRE_STACK_ALIGN_TRAMPOLINE (0) -#elif defined(__x86_64__) -#define ABSL_REQUIRE_STACK_ALIGN_TRAMPOLINE (1) -#define ABSL_ATTRIBUTE_STACK_ALIGN_FOR_OLD_LIBC -#else // !__i386__ && !__x86_64 -#define ABSL_REQUIRE_STACK_ALIGN_TRAMPOLINE (0) -#define ABSL_ATTRIBUTE_STACK_ALIGN_FOR_OLD_LIBC -#endif // __i386__ -#else -#define ABSL_ATTRIBUTE_STACK_ALIGN_FOR_OLD_LIBC -#define ABSL_REQUIRE_STACK_ALIGN_TRAMPOLINE (0) -#endif - -// ABSL_MUST_USE_RESULT -// -// Tells the compiler to warn about unused results. -// -// For code or headers that are assured to only build with C++17 and up, prefer -// just using the standard `[[nodiscard]]` directly over this macro. -// -// When annotating a function, it must appear as the first part of the -// declaration or definition. The compiler will warn if the return value from -// such a function is unused: -// -// ABSL_MUST_USE_RESULT Sprocket* AllocateSprocket(); -// AllocateSprocket(); // Triggers a warning. -// -// When annotating a class, it is equivalent to annotating every function which -// returns an instance. -// -// class ABSL_MUST_USE_RESULT Sprocket {}; -// Sprocket(); // Triggers a warning. -// -// Sprocket MakeSprocket(); -// MakeSprocket(); // Triggers a warning. -// -// Note that references and pointers are not instances: -// -// Sprocket* SprocketPointer(); -// SprocketPointer(); // Does *not* trigger a warning. -// -// ABSL_MUST_USE_RESULT allows using cast-to-void to suppress the unused result -// warning. For that, warn_unused_result is used only for clang but not for gcc. -// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66425 -// -// Note: past advice was to place the macro after the argument list. -// -// TODO(b/176172494): Use ABSL_HAVE_CPP_ATTRIBUTE(nodiscard) when all code is -// compliant with the stricter [[nodiscard]]. -#if defined(__clang__) && ABSL_HAVE_ATTRIBUTE(warn_unused_result) -#define ABSL_MUST_USE_RESULT __attribute__((warn_unused_result)) -#else -#define ABSL_MUST_USE_RESULT -#endif - -// ABSL_ATTRIBUTE_HOT, ABSL_ATTRIBUTE_COLD -// -// Tells GCC that a function is hot or cold. GCC can use this information to -// improve static analysis, i.e. a conditional branch to a cold function -// is likely to be not-taken. -// This annotation is used for function declarations. -// -// Example: -// -// int foo() ABSL_ATTRIBUTE_HOT; -#if ABSL_HAVE_ATTRIBUTE(hot) || (defined(__GNUC__) && !defined(__clang__)) -#define ABSL_ATTRIBUTE_HOT __attribute__((hot)) -#else -#define ABSL_ATTRIBUTE_HOT -#endif - -#if ABSL_HAVE_ATTRIBUTE(cold) || (defined(__GNUC__) && !defined(__clang__)) -#define ABSL_ATTRIBUTE_COLD __attribute__((cold)) -#else -#define ABSL_ATTRIBUTE_COLD -#endif - -// ABSL_XRAY_ALWAYS_INSTRUMENT, ABSL_XRAY_NEVER_INSTRUMENT, ABSL_XRAY_LOG_ARGS -// -// We define the ABSL_XRAY_ALWAYS_INSTRUMENT and ABSL_XRAY_NEVER_INSTRUMENT -// macro used as an attribute to mark functions that must always or never be -// instrumented by XRay. Currently, this is only supported in Clang/LLVM. -// -// For reference on the LLVM XRay instrumentation, see -// http://llvm.org/docs/XRay.html. -// -// A function with the XRAY_ALWAYS_INSTRUMENT macro attribute in its declaration -// will always get the XRay instrumentation sleds. These sleds may introduce -// some binary size and runtime overhead and must be used sparingly. -// -// These attributes only take effect when the following conditions are met: -// -// * The file/target is built in at least C++11 mode, with a Clang compiler -// that supports XRay attributes. -// * The file/target is built with the -fxray-instrument flag set for the -// Clang/LLVM compiler. -// * The function is defined in the translation unit (the compiler honors the -// attribute in either the definition or the declaration, and must match). -// -// There are cases when, even when building with XRay instrumentation, users -// might want to control specifically which functions are instrumented for a -// particular build using special-case lists provided to the compiler. These -// special case lists are provided to Clang via the -// -fxray-always-instrument=... and -fxray-never-instrument=... flags. The -// attributes in source take precedence over these special-case lists. -// -// To disable the XRay attributes at build-time, users may define -// ABSL_NO_XRAY_ATTRIBUTES. Do NOT define ABSL_NO_XRAY_ATTRIBUTES on specific -// packages/targets, as this may lead to conflicting definitions of functions at -// link-time. -// -// XRay isn't currently supported on Android: -// https://github.com/android/ndk/issues/368 -#if ABSL_HAVE_CPP_ATTRIBUTE(clang::xray_always_instrument) && \ - !defined(ABSL_NO_XRAY_ATTRIBUTES) && !defined(__ANDROID__) -#define ABSL_XRAY_ALWAYS_INSTRUMENT [[clang::xray_always_instrument]] -#define ABSL_XRAY_NEVER_INSTRUMENT [[clang::xray_never_instrument]] -#if ABSL_HAVE_CPP_ATTRIBUTE(clang::xray_log_args) -#define ABSL_XRAY_LOG_ARGS(N) \ - [[clang::xray_always_instrument, clang::xray_log_args(N)]] -#else -#define ABSL_XRAY_LOG_ARGS(N) [[clang::xray_always_instrument]] -#endif -#else -#define ABSL_XRAY_ALWAYS_INSTRUMENT -#define ABSL_XRAY_NEVER_INSTRUMENT -#define ABSL_XRAY_LOG_ARGS(N) -#endif - -// ABSL_ATTRIBUTE_REINITIALIZES -// -// Indicates that a member function reinitializes the entire object to a known -// state, independent of the previous state of the object. -// -// The clang-tidy check bugprone-use-after-move allows member functions marked -// with this attribute to be called on objects that have been moved from; -// without the attribute, this would result in a use-after-move warning. -#if ABSL_HAVE_CPP_ATTRIBUTE(clang::reinitializes) -#define ABSL_ATTRIBUTE_REINITIALIZES [[clang::reinitializes]] -#else -#define ABSL_ATTRIBUTE_REINITIALIZES -#endif - -// ----------------------------------------------------------------------------- -// Variable Attributes -// ----------------------------------------------------------------------------- - -// ABSL_ATTRIBUTE_UNUSED -// -// Prevents the compiler from complaining about variables that appear unused. -// -// For code or headers that are assured to only build with C++17 and up, prefer -// just using the standard '[[maybe_unused]]' directly over this macro. -// -// Due to differences in positioning requirements between the old, compiler -// specific __attribute__ syntax and the now standard [[maybe_unused]], this -// macro does not attempt to take advantage of '[[maybe_unused]]'. -#if ABSL_HAVE_ATTRIBUTE(unused) || (defined(__GNUC__) && !defined(__clang__)) -#undef ABSL_ATTRIBUTE_UNUSED -#define ABSL_ATTRIBUTE_UNUSED __attribute__((__unused__)) -#else -#define ABSL_ATTRIBUTE_UNUSED -#endif - -// ABSL_ATTRIBUTE_INITIAL_EXEC -// -// Tells the compiler to use "initial-exec" mode for a thread-local variable. -// See http://people.redhat.com/drepper/tls.pdf for the gory details. -#if ABSL_HAVE_ATTRIBUTE(tls_model) || (defined(__GNUC__) && !defined(__clang__)) -#define ABSL_ATTRIBUTE_INITIAL_EXEC __attribute__((tls_model("initial-exec"))) -#else -#define ABSL_ATTRIBUTE_INITIAL_EXEC -#endif - -// ABSL_ATTRIBUTE_PACKED -// -// Instructs the compiler not to use natural alignment for a tagged data -// structure, but instead to reduce its alignment to 1. -// -// Therefore, DO NOT APPLY THIS ATTRIBUTE TO STRUCTS CONTAINING ATOMICS. Doing -// so can cause atomic variables to be mis-aligned and silently violate -// atomicity on x86. -// -// This attribute can either be applied to members of a structure or to a -// structure in its entirety. Applying this attribute (judiciously) to a -// structure in its entirety to optimize the memory footprint of very -// commonly-used structs is fine. Do not apply this attribute to a structure in -// its entirety if the purpose is to control the offsets of the members in the -// structure. Instead, apply this attribute only to structure members that need -// it. -// -// When applying ABSL_ATTRIBUTE_PACKED only to specific structure members the -// natural alignment of structure members not annotated is preserved. Aligned -// member accesses are faster than non-aligned member accesses even if the -// targeted microprocessor supports non-aligned accesses. -#if ABSL_HAVE_ATTRIBUTE(packed) || (defined(__GNUC__) && !defined(__clang__)) -#define ABSL_ATTRIBUTE_PACKED __attribute__((__packed__)) -#else -#define ABSL_ATTRIBUTE_PACKED -#endif - -// ABSL_ATTRIBUTE_FUNC_ALIGN -// -// Tells the compiler to align the function start at least to certain -// alignment boundary -#if ABSL_HAVE_ATTRIBUTE(aligned) || (defined(__GNUC__) && !defined(__clang__)) -#define ABSL_ATTRIBUTE_FUNC_ALIGN(bytes) __attribute__((aligned(bytes))) -#else -#define ABSL_ATTRIBUTE_FUNC_ALIGN(bytes) -#endif - -// ABSL_FALLTHROUGH_INTENDED -// -// Annotates implicit fall-through between switch labels, allowing a case to -// indicate intentional fallthrough and turn off warnings about any lack of a -// `break` statement. The ABSL_FALLTHROUGH_INTENDED macro should be followed by -// a semicolon and can be used in most places where `break` can, provided that -// no statements exist between it and the next switch label. -// -// Example: -// -// switch (x) { -// case 40: -// case 41: -// if (truth_is_out_there) { -// ++x; -// ABSL_FALLTHROUGH_INTENDED; // Use instead of/along with annotations -// // in comments -// } else { -// return x; -// } -// case 42: -// ... -// -// Notes: When supported, GCC and Clang can issue a warning on switch labels -// with unannotated fallthrough using the warning `-Wimplicit-fallthrough`. See -// clang documentation on language extensions for details: -// https://clang.llvm.org/docs/AttributeReference.html#fallthrough-clang-fallthrough -// -// When used with unsupported compilers, the ABSL_FALLTHROUGH_INTENDED macro has -// no effect on diagnostics. In any case this macro has no effect on runtime -// behavior and performance of code. - -#ifdef ABSL_FALLTHROUGH_INTENDED -#error "ABSL_FALLTHROUGH_INTENDED should not be defined." -#elif ABSL_HAVE_CPP_ATTRIBUTE(fallthrough) -#define ABSL_FALLTHROUGH_INTENDED [[fallthrough]] -#elif ABSL_HAVE_CPP_ATTRIBUTE(clang::fallthrough) -#define ABSL_FALLTHROUGH_INTENDED [[clang::fallthrough]] -#elif ABSL_HAVE_CPP_ATTRIBUTE(gnu::fallthrough) -#define ABSL_FALLTHROUGH_INTENDED [[gnu::fallthrough]] -#else -#define ABSL_FALLTHROUGH_INTENDED \ - do { \ - } while (0) -#endif - -// ABSL_DEPRECATED() -// -// Marks a deprecated class, struct, enum, function, method and variable -// declarations. The macro argument is used as a custom diagnostic message (e.g. -// suggestion of a better alternative). -// -// For code or headers that are assured to only build with C++14 and up, prefer -// just using the standard `[[deprecated("message")]]` directly over this macro. -// -// Examples: -// -// class ABSL_DEPRECATED("Use Bar instead") Foo {...}; -// -// ABSL_DEPRECATED("Use Baz() instead") void Bar() {...} -// -// template -// ABSL_DEPRECATED("Use DoThat() instead") -// void DoThis(); -// -// enum FooEnum { -// kBar ABSL_DEPRECATED("Use kBaz instead"), -// }; -// -// Every usage of a deprecated entity will trigger a warning when compiled with -// GCC/Clang's `-Wdeprecated-declarations` option. Google's production toolchain -// turns this warning off by default, instead relying on clang-tidy to report -// new uses of deprecated code. -#if ABSL_HAVE_ATTRIBUTE(deprecated) -#define ABSL_DEPRECATED(message) __attribute__((deprecated(message))) -#else -#define ABSL_DEPRECATED(message) -#endif - -// When deprecating Abseil code, it is sometimes necessary to turn off the -// warning within Abseil, until the deprecated code is actually removed. The -// deprecated code can be surrounded with these directives to achieve that -// result. -// -// class ABSL_DEPRECATED("Use Bar instead") Foo; -// -// ABSL_INTERNAL_DISABLE_DEPRECATED_DECLARATION_WARNING -// Baz ComputeBazFromFoo(Foo f); -// ABSL_INTERNAL_RESTORE_DEPRECATED_DECLARATION_WARNING -#if defined(__GNUC__) || defined(__clang__) -// Clang also supports these GCC pragmas. -#define ABSL_INTERNAL_DISABLE_DEPRECATED_DECLARATION_WARNING \ - _Pragma("GCC diagnostic push") \ - _Pragma("GCC diagnostic ignored \"-Wdeprecated-declarations\"") -#define ABSL_INTERNAL_RESTORE_DEPRECATED_DECLARATION_WARNING \ - _Pragma("GCC diagnostic pop") -#else -#define ABSL_INTERNAL_DISABLE_DEPRECATED_DECLARATION_WARNING -#define ABSL_INTERNAL_RESTORE_DEPRECATED_DECLARATION_WARNING -#endif // defined(__GNUC__) || defined(__clang__) - -// ABSL_CONST_INIT -// -// A variable declaration annotated with the `ABSL_CONST_INIT` attribute will -// not compile (on supported platforms) unless the variable has a constant -// initializer. This is useful for variables with static and thread storage -// duration, because it guarantees that they will not suffer from the so-called -// "static init order fiasco". -// -// This attribute must be placed on the initializing declaration of the -// variable. Some compilers will give a -Wmissing-constinit warning when this -// attribute is placed on some other declaration but missing from the -// initializing declaration. -// -// In some cases (notably with thread_local variables), `ABSL_CONST_INIT` can -// also be used in a non-initializing declaration to tell the compiler that a -// variable is already initialized, reducing overhead that would otherwise be -// incurred by a hidden guard variable. Thus annotating all declarations with -// this attribute is recommended to potentially enhance optimization. -// -// Example: -// -// class MyClass { -// public: -// ABSL_CONST_INIT static MyType my_var; -// }; -// -// ABSL_CONST_INIT MyType MyClass::my_var = MakeMyType(...); -// -// For code or headers that are assured to only build with C++20 and up, prefer -// just using the standard `constinit` keyword directly over this macro. -// -// Note that this attribute is redundant if the variable is declared constexpr. -#if defined(__cpp_constinit) && __cpp_constinit >= 201907L -#define ABSL_CONST_INIT constinit -#elif ABSL_HAVE_CPP_ATTRIBUTE(clang::require_constant_initialization) -#define ABSL_CONST_INIT [[clang::require_constant_initialization]] -#else -#define ABSL_CONST_INIT -#endif - -// ABSL_ATTRIBUTE_PURE_FUNCTION -// -// ABSL_ATTRIBUTE_PURE_FUNCTION is used to annotate declarations of "pure" -// functions. A function is pure if its return value is only a function of its -// arguments. The pure attribute prohibits a function from modifying the state -// of the program that is observable by means other than inspecting the -// function's return value. Declaring such functions with the pure attribute -// allows the compiler to avoid emitting some calls in repeated invocations of -// the function with the same argument values. -// -// Example: -// -// ABSL_ATTRIBUTE_PURE_FUNCTION std::string FormatTime(Time t); -#if ABSL_HAVE_CPP_ATTRIBUTE(gnu::pure) -#define ABSL_ATTRIBUTE_PURE_FUNCTION [[gnu::pure]] -#elif ABSL_HAVE_ATTRIBUTE(pure) -#define ABSL_ATTRIBUTE_PURE_FUNCTION __attribute__((pure)) -#else -// If the attribute isn't defined, we'll fallback to ABSL_MUST_USE_RESULT since -// pure functions are useless if its return is ignored. -#define ABSL_ATTRIBUTE_PURE_FUNCTION ABSL_MUST_USE_RESULT -#endif - -// ABSL_ATTRIBUTE_CONST_FUNCTION -// -// ABSL_ATTRIBUTE_CONST_FUNCTION is used to annotate declarations of "const" -// functions. A const function is similar to a pure function, with one -// exception: Pure functions may return value that depend on a non-volatile -// object that isn't provided as a function argument, while the const function -// is guaranteed to return the same result given the same arguments. -// -// Example: -// -// ABSL_ATTRIBUTE_CONST_FUNCTION int64_t ToInt64Milliseconds(Duration d); -#if defined(_MSC_VER) && !defined(__clang__) -// Put the MSVC case first since MSVC seems to parse const as a C++ keyword. -#define ABSL_ATTRIBUTE_CONST_FUNCTION ABSL_ATTRIBUTE_PURE_FUNCTION -#elif ABSL_HAVE_CPP_ATTRIBUTE(gnu::const) -#define ABSL_ATTRIBUTE_CONST_FUNCTION [[gnu::const]] -#elif ABSL_HAVE_ATTRIBUTE(const) -#define ABSL_ATTRIBUTE_CONST_FUNCTION __attribute__((const)) -#else -// Since const functions are more restrictive pure function, we'll fallback to a -// pure function if the const attribute is not handled. -#define ABSL_ATTRIBUTE_CONST_FUNCTION ABSL_ATTRIBUTE_PURE_FUNCTION -#endif - -// ABSL_ATTRIBUTE_LIFETIME_BOUND indicates that a resource owned by a function -// parameter or implicit object parameter is retained by the return value of the -// annotated function (or, for a parameter of a constructor, in the value of the -// constructed object). This attribute causes warnings to be produced if a -// temporary object does not live long enough. -// -// When applied to a reference parameter, the referenced object is assumed to be -// retained by the return value of the function. When applied to a non-reference -// parameter (for example, a pointer or a class type), all temporaries -// referenced by the parameter are assumed to be retained by the return value of -// the function. -// -// See also the upstream documentation: -// https://clang.llvm.org/docs/AttributeReference.html#lifetimebound -#if ABSL_HAVE_CPP_ATTRIBUTE(clang::lifetimebound) -#define ABSL_ATTRIBUTE_LIFETIME_BOUND [[clang::lifetimebound]] -#elif ABSL_HAVE_ATTRIBUTE(lifetimebound) -#define ABSL_ATTRIBUTE_LIFETIME_BOUND __attribute__((lifetimebound)) -#else -#define ABSL_ATTRIBUTE_LIFETIME_BOUND -#endif - -// ABSL_ATTRIBUTE_TRIVIAL_ABI -// Indicates that a type is "trivially relocatable" -- meaning it can be -// relocated without invoking the constructor/destructor, using a form of move -// elision. -// -// From a memory safety point of view, putting aside destructor ordering, it's -// safe to apply ABSL_ATTRIBUTE_TRIVIAL_ABI if an object's location -// can change over the course of its lifetime: if a constructor can be run one -// place, and then the object magically teleports to another place where some -// methods are run, and then the object teleports to yet another place where it -// is destroyed. This is notably not true for self-referential types, where the -// move-constructor must keep the self-reference up to date. If the type changed -// location without invoking the move constructor, it would have a dangling -// self-reference. -// -// The use of this teleporting machinery means that the number of paired -// move/destroy operations can change, and so it is a bad idea to apply this to -// a type meant to count the number of moves. -// -// Warning: applying this can, rarely, break callers. Objects passed by value -// will be destroyed at the end of the call, instead of the end of the -// full-expression containing the call. In addition, it changes the ABI -// of functions accepting this type by value (e.g. to pass in registers). -// -// See also the upstream documentation: -// https://clang.llvm.org/docs/AttributeReference.html#trivial-abi -// -// b/321691395 - This is currently disabled in open-source builds since -// compiler support differs. If system libraries compiled with GCC are mixed -// with libraries compiled with Clang, types will have different ideas about -// their ABI, leading to hard to debug crashes. -#define ABSL_ATTRIBUTE_TRIVIAL_ABI - -// ABSL_ATTRIBUTE_NO_UNIQUE_ADDRESS -// -// Indicates a data member can be optimized to occupy no space (if it is empty) -// and/or its tail padding can be used for other members. -// -// For code that is assured to only build with C++20 or later, prefer using -// the standard attribute `[[no_unique_address]]` directly instead of this -// macro. -// -// https://devblogs.microsoft.com/cppblog/msvc-cpp20-and-the-std-cpp20-switch/#c20-no_unique_address -// Current versions of MSVC have disabled `[[no_unique_address]]` since it -// breaks ABI compatibility, but offers `[[msvc::no_unique_address]]` for -// situations when it can be assured that it is desired. Since Abseil does not -// claim ABI compatibility in mixed builds, we can offer it unconditionally. -#if defined(_MSC_VER) && _MSC_VER >= 1929 -#define ABSL_ATTRIBUTE_NO_UNIQUE_ADDRESS [[msvc::no_unique_address]] -#elif ABSL_HAVE_CPP_ATTRIBUTE(no_unique_address) -#define ABSL_ATTRIBUTE_NO_UNIQUE_ADDRESS [[no_unique_address]] -#else -#define ABSL_ATTRIBUTE_NO_UNIQUE_ADDRESS -#endif - -// ABSL_ATTRIBUTE_UNINITIALIZED -// -// GCC and Clang support a flag `-ftrivial-auto-var-init=