首次提交
This commit is contained in:
19
Pods/SDWebImageWebPCoder/LICENSE
generated
Normal file
19
Pods/SDWebImageWebPCoder/LICENSE
generated
Normal file
@@ -0,0 +1,19 @@
|
||||
Copyright (c) 2018 Bogdan Poplauschi
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
318
Pods/SDWebImageWebPCoder/README.md
generated
Normal file
318
Pods/SDWebImageWebPCoder/README.md
generated
Normal file
@@ -0,0 +1,318 @@
|
||||
# SDWebImageWebPCoder
|
||||
|
||||
[](https://travis-ci.org/SDWebImage/SDWebImageWebPCoder)
|
||||
[](http://cocoapods.org/pods/SDWebImageWebPCoder)
|
||||
[](http://cocoapods.org/pods/SDWebImageWebPCoder)
|
||||
[](http://cocoapods.org/pods/SDWebImageWebPCoder)
|
||||
[](https://swift.org/package-manager/)
|
||||
[](https://github.com/SDWebImage/SDWebImageWebPCoder)
|
||||
[](https://codecov.io/gh/SDWebImage/SDWebImageWebPCoder)
|
||||
|
||||
Starting with the SDWebImage 5.0 version, we moved the WebP support code and [libwebp](https://github.com/webmproject/libwebp) from the Core Repo to this stand-alone repo.
|
||||
|
||||
SDWebImageWebPCoder supports both WebP decoding and encoding, for Static WebP or Animated WebP as well.
|
||||
|
||||
Note: Apple's ImageIO supports WebP decoding from iOS 14/tvOS 14/watchOS 7/macOS 11, so SDWebImage on those platform can also decode WebP images (using `SDWebImageAWebPCoder` built-in coder). However it may contains some limitation, check https://github.com/SDWebImage/SDWebImage/issues/3558, you can still force to use this coder on those platforms by adding this coder.
|
||||
|
||||
## Requirements
|
||||
|
||||
+ iOS 9.0
|
||||
+ macOS 10.11
|
||||
+ tvOS 9.0
|
||||
+ watchOS 2.0
|
||||
+ Xcode 11.0
|
||||
|
||||
## Installation
|
||||
|
||||
#### CocoaPods
|
||||
|
||||
SDWebImageWebPCoder is available through [CocoaPods](http://cocoapods.org). To install it, simply add the following line to your Podfile:
|
||||
|
||||
```ruby
|
||||
pod 'SDWebImageWebPCoder'
|
||||
```
|
||||
|
||||
#### Carthage
|
||||
|
||||
SDWebImageWebPCoder is available through [Carthage](https://github.com/Carthage/Carthage).
|
||||
|
||||
```
|
||||
github "SDWebImage/SDWebImageWebPCoder"
|
||||
```
|
||||
|
||||
#### Swift Package Manager (Xcode 11+)
|
||||
|
||||
SDWebImageWebPCoder is available through [Swift Package Manager](https://swift.org/package-manager).
|
||||
|
||||
```swift
|
||||
let package = Package(
|
||||
dependencies: [
|
||||
.package(url: "https://github.com/SDWebImage/SDWebImageWebPCoder.git", from: "0.3.0")
|
||||
]
|
||||
)
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### Add Coder
|
||||
|
||||
Before using SDWebImage to load WebP images, you need to register the WebP Coder to your coders manager. This step is recommended to be done after your App launch (like AppDelegate method).
|
||||
|
||||
+ Objective-C
|
||||
|
||||
```objective-c
|
||||
// Add coder
|
||||
SDImageWebPCoder *webPCoder = [SDImageWebPCoder sharedCoder];
|
||||
[[SDImageCodersManager sharedManager] addCoder:webPCoder];
|
||||
```
|
||||
|
||||
+ Swift
|
||||
|
||||
```swift
|
||||
// Add coder
|
||||
let WebPCoder = SDImageWebPCoder.shared
|
||||
SDImageCodersManager.shared.addCoder(WebPCoder)
|
||||
```
|
||||
|
||||
### Modify HTTP Accept Header
|
||||
|
||||
Some of image server provider may try to detect the client supported format, by default, SDWebImage use `image/*,*/*;q=0.8` for [Accept](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept). You can modify it with the `image/webp` as well.
|
||||
|
||||
+ Objective-C
|
||||
|
||||
```objective-c
|
||||
[[SDWebImageDownloader sharedDownloader] setValue:@"image/webp,image/*,*/*;q=0.8" forHTTPHeaderField:@"Accept"];
|
||||
```
|
||||
|
||||
+ Swift
|
||||
|
||||
```swift
|
||||
SDWebImageDownloader.shared.setValue("image/webp,image/*,*/*;q=0.8", forHTTPHeaderField:"Accept")
|
||||
```
|
||||
|
||||
### Loading
|
||||
|
||||
+ Objective-C
|
||||
|
||||
```objective-c
|
||||
// WebP online image loading
|
||||
NSURL *webpURL;
|
||||
UIImageView *imageView;
|
||||
[imageView sd_setImageWithURL:webpURL];
|
||||
```
|
||||
|
||||
+ Swift
|
||||
|
||||
```swift
|
||||
// WebP online image loading
|
||||
let webpURL: URL
|
||||
let imageView: UIImageView
|
||||
imageView.sd_setImage(with: webpURL)
|
||||
```
|
||||
|
||||
### Progressive Animation Loading (0.5.0+)
|
||||
|
||||
+ Objective-C
|
||||
|
||||
```objective-c
|
||||
// WebP progressive loading for animated image
|
||||
NSURL *webpURL;
|
||||
SDAnimatedImageView *imageView;
|
||||
imageView.shouldIncrementalLoad = YES;
|
||||
[imageView sd_setImageWithURL:webpURL placeholderImage:nil options:SDWebImageProgressiveLoad];
|
||||
```
|
||||
|
||||
+ Swift
|
||||
|
||||
```swift
|
||||
// WebP progressive loading for animated image
|
||||
let webpURL: URL
|
||||
let imageView: SDAnimatedImageView
|
||||
imageView.shouldIncrementalLoad = true
|
||||
imageView.sd_setImage(with: webpURL, placeholderImage: nil, options: [.progressiveLoad])
|
||||
```
|
||||
|
||||
### Decoding
|
||||
|
||||
+ Objective-C
|
||||
|
||||
```objective-c
|
||||
// WebP image decoding
|
||||
NSData *webpData;
|
||||
UIImage *image = [[SDImageWebPCoder sharedCoder] decodedImageWithData:webpData options:nil];
|
||||
```
|
||||
|
||||
+ Swift
|
||||
|
||||
```swift
|
||||
// WebP image decoding
|
||||
let webpData: Data
|
||||
let image = SDImageWebPCoder.shared.decodedImage(with: data, options: nil)
|
||||
```
|
||||
|
||||
### Thumbnail Decoding (0.4.0+)
|
||||
|
||||
+ Objective-C
|
||||
|
||||
```objective-c
|
||||
// WebP thumbnail image decoding
|
||||
NSData *webpData;
|
||||
CGSize thumbnailSize = CGSizeMake(300, 300);
|
||||
UIImage *thumbnailImage = [[SDImageWebPCoder sharedCoder] decodedImageWithData:webpData options:@{SDImageCoderDecodeThumbnailPixelSize : @(thumbnailSize)}];
|
||||
```
|
||||
|
||||
+ Swift
|
||||
|
||||
```swift
|
||||
// WebP thumbnail image decoding
|
||||
let webpData: Data
|
||||
let thumbnailSize = CGSize(width: 300, height: 300)
|
||||
let image = SDImageWebPCoder.shared.decodedImage(with: data, options: [.decodeThumbnailPixelSize: thumbnailSize])
|
||||
```
|
||||
|
||||
### Decoding with limit bytes (0.12.0+)
|
||||
|
||||
+ Objective-C
|
||||
|
||||
```objective-c
|
||||
// WebP thumbnail image decoding
|
||||
NSData *webpData;
|
||||
NSUInteger limitBytes = 1024 * 1024; // 1MB
|
||||
UIImage *image = [[SDImageWebPCoder sharedCoder] decodedImageWithData:webpData options:@{SDImageCoderDecodeScaleDownLimitBytes : @(limitBytes)}];
|
||||
// The image pixel buffer is guaranteed to less than 1MB in RAM (may scale down or full size), suitable for large image
|
||||
```
|
||||
|
||||
+ Swift
|
||||
|
||||
```swift
|
||||
// WebP thumbnail image decoding
|
||||
let webpData: Data
|
||||
let limitBytes = 1024 * 1024 // 1MB
|
||||
let image = SDImageWebPCoder.shared.decodedImage(with: data, options: [.decodeScaleDownLimitBytes: limitBytes])
|
||||
// The image pixel buffer is guaranteed to less than 1MB in RAM (may scale down or full size), suitable for large image
|
||||
```
|
||||
|
||||
### Encoding
|
||||
|
||||
+ Objective-c
|
||||
|
||||
```objective-c
|
||||
// WebP image encoding
|
||||
UIImage *image;
|
||||
NSData *webpData = [[SDImageWebPCoder sharedCoder] encodedDataWithImage:image format:SDImageFormatWebP options:nil];
|
||||
// Animated encoding
|
||||
NSArray<SDImageFrames *> *frames;
|
||||
NSData *awebpData = [[SDImageWebPCoder sharedCoder] encodedDataWithFrames:frames loopCount:0 format:SDImageFormatWebP options:nil];
|
||||
// Encode Quality
|
||||
NSData *lossyWebpData = [[SDImageWebPCoder sharedCoder] encodedDataWithImage:image format:SDImageFormatWebP options:@{SDImageCoderEncodeCompressionQuality : @(0.1)}]; // [0, 1] compression quality
|
||||
NSData *limitedWebpData = [[SDImageWebPCoder sharedCoder] encodedDataWithImage:image format:SDImageFormatWebP options:@{SDImageCoderEncodeMaxFileSize : @(1024 * 10)}]; // v0.6.0 feature, limit output file size <= 10KB
|
||||
```
|
||||
|
||||
+ Swift
|
||||
|
||||
```swift
|
||||
// WebP image encoding
|
||||
let image: UIImage
|
||||
let webpData = SDImageWebPCoder.shared.encodedData(with: image, format: .webP, options: nil)
|
||||
// Animated encoding
|
||||
let frames: [SDImageFrame]
|
||||
let awebpData = SDImageWebPCoder.shared.encodedData(with: frames, loopCount: 0, format: .webP, options: nil)
|
||||
// Encode Quality
|
||||
let lossyWebpData = SDImageWebPCoder.shared.encodedData(with: image, format: .webP, options: [.encodeCompressionQuality: 0.1]) // [0, 1] compression quality
|
||||
let limitedWebpData = SDImageWebPCoder.shared.encodedData(with: image, format: .webP, options: [.encodeMaxFileSize: 1024 * 10]) // v0.6.0 feature, limit output file size <= 10KB
|
||||
```
|
||||
|
||||
### Thumbnail Encoding (0.6.1+)
|
||||
|
||||
+ Objective-C
|
||||
|
||||
```objective-c
|
||||
// WebP image thumbnail encoding
|
||||
UIImage *image;
|
||||
NSData *thumbnailWebpData = [[SDImageWebPCoder sharedCoder] encodedDataWithImage:image format:SDImageFormatWebP options:@{SDImageCoderEncodeMaxPixelSize : @(CGSizeMake(200, 200))}]; // v0.6.1 feature, encoding max pixel size
|
||||
```
|
||||
|
||||
+ Swift
|
||||
|
||||
```swift
|
||||
// WebP image thumbnail encoding
|
||||
let image: UIImage
|
||||
let thumbnailWebpData = SDImageWebPCoder.shared.encodedData(with: image, format: .webP, options: [.encodeMaxPixelSize: CGSize(width: 200, height: 200)]) // v0.6.1 feature, encoding max pixel size
|
||||
```
|
||||
|
||||
See more documentation in [SDWebImage Wiki - Coders](https://github.com/SDWebImage/SDWebImage/wiki/Advanced-Usage#custom-coder-420)
|
||||
|
||||
### Animated WebP Encoding (0.10+)
|
||||
|
||||
+ Objective-c
|
||||
|
||||
```objective-c
|
||||
// Animated encoding
|
||||
NSMutableArray<SDImageFrames *> *frames = [NSMutableArray array];
|
||||
for (size_t i = 0; i < images.count; i++) {
|
||||
SDImageFrame *frame = [SDImageFrame frameWithImage:images[i] duration:0.1];
|
||||
[frames appendObject:frame];
|
||||
}
|
||||
NSData *awebpData = [[SDImageWebPCoder sharedCoder] encodedDataWithFrames:frames loopCount:0 format:SDImageFormatWebP options:nil];
|
||||
```
|
||||
|
||||
+ Swift
|
||||
|
||||
```swift
|
||||
// Animated encoding
|
||||
var frames: [SDImageFrame] = []
|
||||
for i in 0..<images.count {
|
||||
let frame = SDImageFrame(image: images[i], duration: 0.1)
|
||||
frames.append(frame)
|
||||
}
|
||||
let awebpData = SDImageWebPCoder.shared.encodedData(with: frames, loopCount: 0, format: .webP, options: nil)
|
||||
```
|
||||
|
||||
### Advanced WebP codec options (0.8+)
|
||||
|
||||
The WebP codec [libwebp](https://developers.google.com/speed/webp/docs/api) we use, supports some advanced control options for encoding/decoding. You can pass them to libwebp by using the wrapper top level API:
|
||||
|
||||
+ Objective-C
|
||||
|
||||
```objective-c
|
||||
UIImage *image;
|
||||
SDImageCoderOptions *options = @{SDImageCoderEncodeWebPMethod: @(0), SDImageCoderEncodeWebPAlphaCompression: @(100)};
|
||||
NSData *data = [SDImageWebPCoder.sharedCoder encodedDataWithImage:image format:SDImageFormatWebP options:options];
|
||||
// Will translate into:
|
||||
// config->method = 0;
|
||||
// config->alpha_quality = 100;
|
||||
```
|
||||
|
||||
+ Swift
|
||||
|
||||
```swift
|
||||
let image: UIImage
|
||||
let options = [.encodeWebPMethod: 0, .encodeWebPAlphaCompression: 100]
|
||||
let data = SDImageWebPCoder.shared.encodedData(with: image, format: .webP, options: options)
|
||||
// Will translate into:
|
||||
// config->method = 0;
|
||||
// config->alpha_quality = 100;
|
||||
```
|
||||
|
||||
## Example
|
||||
|
||||
To run the example project, clone the repo, and run `pod install` from the root directory first. Then open `SDWebImageWebPCoder.xcworkspace`.
|
||||
|
||||
This is a demo to show how to use `WebP` and animated `WebP` images via `SDWebImageWebPCoderExample` target.
|
||||
|
||||
## Screenshot
|
||||
|
||||
<img src="https://raw.githubusercontent.com/SDWebImage/SDWebImageWebPCoder/master/Example/Screenshot/WebPDemo.png" width="300" />
|
||||
|
||||
These WebP images are from [WebP Gallery](https://developers.google.com/speed/webp/gallery1) and [GIF vs APNG vs WebP](http://littlesvr.ca/apng/gif_apng_webp.html)
|
||||
|
||||
## Author
|
||||
|
||||
[Bogdan Poplauschi](https://github.com/bpoplauschi)
|
||||
[DreamPiggy](https://github.com/dreampiggy)
|
||||
|
||||
## License
|
||||
|
||||
SDWebImageWebPCoder is available under the MIT license. See [the LICENSE file](https://github.com/SDWebImage/SDWebImageWebPCoder/blob/master/LICENSE) for more info.
|
||||
|
||||
|
||||
22
Pods/SDWebImageWebPCoder/SDWebImageWebPCoder/Classes/SDImageWebPCoder.h
generated
Normal file
22
Pods/SDWebImageWebPCoder/SDWebImageWebPCoder/Classes/SDImageWebPCoder.h
generated
Normal file
@@ -0,0 +1,22 @@
|
||||
/*
|
||||
* This file is part of the SDWebImage package.
|
||||
* (c) Olivier Poitrey <rs@dailymotion.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
#if __has_include(<SDWebImage/SDWebImage.h>)
|
||||
#import <SDWebImage/SDWebImage.h>
|
||||
#else
|
||||
@import SDWebImage;
|
||||
#endif
|
||||
|
||||
/**
|
||||
Built in coder that supports WebP and animated WebP
|
||||
*/
|
||||
@interface SDImageWebPCoder : NSObject <SDProgressiveImageCoder, SDAnimatedImageCoder>
|
||||
|
||||
@property (nonatomic, class, readonly, nonnull) SDImageWebPCoder *sharedCoder;
|
||||
|
||||
@end
|
||||
1348
Pods/SDWebImageWebPCoder/SDWebImageWebPCoder/Classes/SDImageWebPCoder.m
generated
Normal file
1348
Pods/SDWebImageWebPCoder/SDWebImageWebPCoder/Classes/SDImageWebPCoder.m
generated
Normal file
File diff suppressed because it is too large
Load Diff
143
Pods/SDWebImageWebPCoder/SDWebImageWebPCoder/Classes/SDWebImageWebPCoderDefine.h
generated
Normal file
143
Pods/SDWebImageWebPCoder/SDWebImageWebPCoder/Classes/SDWebImageWebPCoderDefine.h
generated
Normal file
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
* This file is part of the SDWebImage package.
|
||||
* (c) Olivier Poitrey <rs@dailymotion.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
#if __has_include(<SDWebImage/SDWebImage.h>)
|
||||
#import <SDWebImage/SDWebImage.h>
|
||||
#else
|
||||
@import SDWebImage;
|
||||
#endif
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
/**
|
||||
Integer value
|
||||
Quality/speed trade-off (0=fast, 6=slower-better)
|
||||
*/
|
||||
FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPMethod;
|
||||
|
||||
/**
|
||||
Integer value
|
||||
Number of entropy-analysis passes (in [1..10])
|
||||
*/
|
||||
FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPPass;
|
||||
|
||||
/**
|
||||
Integer value
|
||||
Preprocessing filter (0=none, 1=segment-smooth)
|
||||
*/
|
||||
FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPPreprocessing;
|
||||
|
||||
/**
|
||||
Float value
|
||||
if non-zero, specifies the minimal distortion to try to achieve. Takes precedence over target_size.
|
||||
*/
|
||||
FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPTargetPSNR;
|
||||
|
||||
/**
|
||||
Integer value
|
||||
If non-zero, try and use multi-threaded encoding.
|
||||
*/
|
||||
FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPThreadLevel;
|
||||
|
||||
/**
|
||||
Integer value
|
||||
If set, reduce memory usage (but increase CPU use).
|
||||
*/
|
||||
FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPLowMemory;
|
||||
|
||||
/**
|
||||
Integer value
|
||||
if non-zero, specifies the minimal distortion to try to achieve. Takes precedence over target_size.
|
||||
*/
|
||||
FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPSegments;
|
||||
|
||||
/**
|
||||
Integer value
|
||||
Spatial Noise Shaping. 0=off, 100=maximum.
|
||||
*/
|
||||
FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPSnsStrength;
|
||||
|
||||
/**
|
||||
Integer value
|
||||
Range: [0 = off .. 100 = strongest]
|
||||
*/
|
||||
FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPFilterStrength;
|
||||
|
||||
/**
|
||||
Integer value
|
||||
range: [0 = off .. 7 = least sharp]
|
||||
*/
|
||||
FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPFilterSharpness;
|
||||
|
||||
/**
|
||||
Integer value
|
||||
Filtering type: 0 = simple, 1 = strong (only used If filter_strength > 0 or autofilter > 0)
|
||||
*/
|
||||
FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPFilterType;
|
||||
|
||||
/**
|
||||
Integer value
|
||||
Auto adjust filter's strength [0 = off, 1 = on]
|
||||
*/
|
||||
FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPAutofilter;
|
||||
|
||||
/**
|
||||
Integer value
|
||||
Algorithm for encoding the alpha plane (0 = none, 1 = compressed with WebP lossless). Default is 1.
|
||||
*/
|
||||
FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPAlphaCompression;
|
||||
|
||||
/**
|
||||
Integer value
|
||||
Predictive filtering method for alpha plane. 0: none, 1: fast, 2: best. Default if 1.
|
||||
*/
|
||||
FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPAlphaFiltering;
|
||||
|
||||
/**
|
||||
Integer value
|
||||
Between 0 (smallest size) and 100 (lossless).
|
||||
Default is 100.
|
||||
*/
|
||||
FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPAlphaQuality;
|
||||
|
||||
/**
|
||||
Integer value
|
||||
If true, export the compressed picture back.
|
||||
In-loop filtering is not applied.
|
||||
*/
|
||||
FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPShowCompressed;
|
||||
|
||||
/**
|
||||
Integer
|
||||
Log2(number of token partitions) in [0..3]
|
||||
Default is set to 0 for easier progressive decoding.
|
||||
*/
|
||||
FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPPartitions;
|
||||
|
||||
/**
|
||||
Integer value
|
||||
Quality degradation allowed to fit the 512k limit on
|
||||
Prediction modes coding (0: no degradation, 100: maximum possible degradation).
|
||||
*/
|
||||
FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPPartitionLimit;
|
||||
|
||||
/**
|
||||
Integer value
|
||||
if needed, use sharp (and slow) RGB->YUV conversion
|
||||
*/
|
||||
FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPUseSharpYuv;
|
||||
|
||||
/**
|
||||
0: Disabled, 1: Enabled.
|
||||
Lossless mode. Note that if lossless is enabled, encoder quality param specifies
|
||||
compression effort. 100 means maximum compression.
|
||||
Details on cwebp documentation: https://developers.google.com/speed/webp/docs/cwebp#lossless
|
||||
*/
|
||||
FOUNDATION_EXPORT SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPLossless;
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
29
Pods/SDWebImageWebPCoder/SDWebImageWebPCoder/Classes/SDWebImageWebPCoderDefine.m
generated
Normal file
29
Pods/SDWebImageWebPCoder/SDWebImageWebPCoder/Classes/SDWebImageWebPCoderDefine.m
generated
Normal file
@@ -0,0 +1,29 @@
|
||||
//
|
||||
// SDWebImageWebPCoderDefine.m
|
||||
// SDWebImageWebPCoder
|
||||
//
|
||||
// Created by Antti Kortetmaa on 2020/12/06.
|
||||
//
|
||||
|
||||
#import "SDWebImageWebPCoderDefine.h"
|
||||
|
||||
SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPMethod = @"webPMethod";
|
||||
SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPPass = @"webPPass";
|
||||
SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPPreprocessing = @"webPPreprocessing";
|
||||
SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPThreadLevel = @"webPThreadLevel";
|
||||
SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPLowMemory = @"webPLowMemory";
|
||||
SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPTargetPSNR = @"webPTargetPSNR";
|
||||
SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPSegments = @"webPSegments";
|
||||
SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPSnsStrength = @"webPSnsStrength";
|
||||
SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPFilterStrength = @"webPFilterStrength";
|
||||
SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPFilterSharpness = @"webPFilterSharpness";
|
||||
SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPFilterType = @"webPFilterType";
|
||||
SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPAutofilter = @"webPAutofilter";
|
||||
SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPAlphaCompression = @"webPAlphaCompression";
|
||||
SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPAlphaFiltering = @"webPAlphaFiltering";
|
||||
SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPAlphaQuality = @"webPAlphaQuality";
|
||||
SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPShowCompressed = @"webPShowCompressed";
|
||||
SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPPartitions = @"webPPartitions";
|
||||
SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPPartitionLimit = @"webPPartitionLimit";
|
||||
SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPUseSharpYuv = @"webPUseSharpYuv";
|
||||
SDImageCoderOption _Nonnull const SDImageCoderEncodeWebPLossless = @"webPLossless";
|
||||
27
Pods/SDWebImageWebPCoder/SDWebImageWebPCoder/Classes/UIImage+WebP.h
generated
Normal file
27
Pods/SDWebImageWebPCoder/SDWebImageWebPCoder/Classes/UIImage+WebP.h
generated
Normal file
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* This file is part of the SDWebImage package.
|
||||
* (c) Olivier Poitrey <rs@dailymotion.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
#if __has_include(<SDWebImage/SDWebImage.h>)
|
||||
#import <SDWebImage/SDWebImage.h>
|
||||
#else
|
||||
@import SDWebImage;
|
||||
#endif
|
||||
|
||||
// This category is just use as a convenience method. For more detail control, use methods in `UIImage+MultiFormat.h` or directlly use `SDImageCoder`
|
||||
@interface UIImage (WebP)
|
||||
|
||||
/**
|
||||
Create a image from the WebP data.
|
||||
This will create animated image if the data is Animated WebP. And will create a static image is the data is Static WebP.
|
||||
|
||||
@param data The WebP data
|
||||
@return The created image
|
||||
*/
|
||||
+ (nullable UIImage *)sd_imageWithWebPData:(nullable NSData *)data;
|
||||
|
||||
@end
|
||||
21
Pods/SDWebImageWebPCoder/SDWebImageWebPCoder/Classes/UIImage+WebP.m
generated
Normal file
21
Pods/SDWebImageWebPCoder/SDWebImageWebPCoder/Classes/UIImage+WebP.m
generated
Normal file
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* This file is part of the SDWebImage package.
|
||||
* (c) Olivier Poitrey <rs@dailymotion.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
#import "UIImage+WebP.h"
|
||||
#import "SDImageWebPCoder.h"
|
||||
|
||||
@implementation UIImage (WebP)
|
||||
|
||||
+ (nullable UIImage *)sd_imageWithWebPData:(nullable NSData *)data {
|
||||
if (!data) {
|
||||
return nil;
|
||||
}
|
||||
return [[SDImageWebPCoder sharedCoder] decodedImageWithData:data options:0];
|
||||
}
|
||||
|
||||
@end
|
||||
16
Pods/SDWebImageWebPCoder/SDWebImageWebPCoder/Module/SDWebImageWebPCoder.h
generated
Normal file
16
Pods/SDWebImageWebPCoder/SDWebImageWebPCoder/Module/SDWebImageWebPCoder.h
generated
Normal file
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* This file is part of the SDWebImage package.
|
||||
* (c) Olivier Poitrey <rs@dailymotion.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
FOUNDATION_EXPORT double SDWebImageWebPCoderVersionNumber;
|
||||
FOUNDATION_EXPORT const unsigned char SDWebImageWebPCoderVersionString[];
|
||||
|
||||
#import <SDWebImageWebPCoder/SDImageWebPCoder.h>
|
||||
#import <SDWebImageWebPCoder/SDWebImageWebPCoderDefine.h>
|
||||
#import <SDWebImageWebPCoder/UIImage+WebP.h>
|
||||
6
Pods/SDWebImageWebPCoder/SDWebImageWebPCoder/Module/SDWebImageWebPCoder.modulemap
generated
Normal file
6
Pods/SDWebImageWebPCoder/SDWebImageWebPCoder/Module/SDWebImageWebPCoder.modulemap
generated
Normal file
@@ -0,0 +1,6 @@
|
||||
framework module SDWebImageWebPCoder {
|
||||
umbrella header "SDWebImageWebPCoder.h"
|
||||
|
||||
export *
|
||||
module * { export * }
|
||||
}
|
||||
187
Pods/SDWebImageWebPCoder/SDWebImageWebPCoder/Private/SDInternalMacros.h
generated
Normal file
187
Pods/SDWebImageWebPCoder/SDWebImageWebPCoder/Private/SDInternalMacros.h
generated
Normal file
@@ -0,0 +1,187 @@
|
||||
/*
|
||||
* This file is part of the SDWebImage package.
|
||||
* (c) Olivier Poitrey <rs@dailymotion.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <os/lock.h>
|
||||
#import <libkern/OSAtomic.h>
|
||||
#import "SDmetamacros.h"
|
||||
|
||||
#define SD_USE_OS_UNFAIR_LOCK TARGET_OS_MACCATALYST ||\
|
||||
(__IPHONE_OS_VERSION_MIN_REQUIRED >= __IPHONE_10_0) ||\
|
||||
(__MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_12) ||\
|
||||
(__TV_OS_VERSION_MIN_REQUIRED >= __TVOS_10_0) ||\
|
||||
(__WATCH_OS_VERSION_MIN_REQUIRED >= __WATCHOS_3_0)
|
||||
|
||||
#ifndef SD_LOCK_DECLARE
|
||||
#if SD_USE_OS_UNFAIR_LOCK
|
||||
#define SD_LOCK_DECLARE(lock) os_unfair_lock lock
|
||||
#else
|
||||
#define SD_LOCK_DECLARE(lock) os_unfair_lock lock API_AVAILABLE(ios(10.0), tvos(10), watchos(3), macos(10.12)); \
|
||||
OSSpinLock lock##_deprecated;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef SD_LOCK_DECLARE_STATIC
|
||||
#if SD_USE_OS_UNFAIR_LOCK
|
||||
#define SD_LOCK_DECLARE_STATIC(lock) static os_unfair_lock lock
|
||||
#else
|
||||
#define SD_LOCK_DECLARE_STATIC(lock) static os_unfair_lock lock API_AVAILABLE(ios(10.0), tvos(10), watchos(3), macos(10.12)); \
|
||||
static OSSpinLock lock##_deprecated;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef SD_LOCK_INIT
|
||||
#if SD_USE_OS_UNFAIR_LOCK
|
||||
#define SD_LOCK_INIT(lock) lock = OS_UNFAIR_LOCK_INIT
|
||||
#else
|
||||
#define SD_LOCK_INIT(lock) if (@available(iOS 10, tvOS 10, watchOS 3, macOS 10.12, *)) lock = OS_UNFAIR_LOCK_INIT; \
|
||||
else lock##_deprecated = OS_SPINLOCK_INIT;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef SD_LOCK
|
||||
#if SD_USE_OS_UNFAIR_LOCK
|
||||
#define SD_LOCK(lock) os_unfair_lock_lock(&lock)
|
||||
#else
|
||||
#define SD_LOCK(lock) if (@available(iOS 10, tvOS 10, watchOS 3, macOS 10.12, *)) os_unfair_lock_lock(&lock); \
|
||||
else OSSpinLockLock(&lock##_deprecated);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef SD_UNLOCK
|
||||
#if SD_USE_OS_UNFAIR_LOCK
|
||||
#define SD_UNLOCK(lock) os_unfair_lock_unlock(&lock)
|
||||
#else
|
||||
#define SD_UNLOCK(lock) if (@available(iOS 10, tvOS 10, watchOS 3, macOS 10.12, *)) os_unfair_lock_unlock(&lock); \
|
||||
else OSSpinLockUnlock(&lock##_deprecated);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef SD_OPTIONS_CONTAINS
|
||||
#define SD_OPTIONS_CONTAINS(options, value) (((options) & (value)) == (value))
|
||||
#endif
|
||||
|
||||
#ifndef SD_CSTRING
|
||||
#define SD_CSTRING(str) #str
|
||||
#endif
|
||||
|
||||
#ifndef SD_NSSTRING
|
||||
#define SD_NSSTRING(str) @(SD_CSTRING(str))
|
||||
#endif
|
||||
|
||||
#ifndef SD_SEL_SPI
|
||||
#define SD_SEL_SPI(name) NSSelectorFromString([NSString stringWithFormat:@"_%@", SD_NSSTRING(name)])
|
||||
#endif
|
||||
|
||||
#ifndef weakify
|
||||
#define weakify(...) \
|
||||
sd_keywordify \
|
||||
metamacro_foreach_cxt(sd_weakify_,, __weak, __VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#ifndef strongify
|
||||
#define strongify(...) \
|
||||
sd_keywordify \
|
||||
_Pragma("clang diagnostic push") \
|
||||
_Pragma("clang diagnostic ignored \"-Wshadow\"") \
|
||||
metamacro_foreach(sd_strongify_,, __VA_ARGS__) \
|
||||
_Pragma("clang diagnostic pop")
|
||||
#endif
|
||||
|
||||
#define sd_weakify_(INDEX, CONTEXT, VAR) \
|
||||
CONTEXT __typeof__(VAR) metamacro_concat(VAR, _weak_) = (VAR);
|
||||
|
||||
#define sd_strongify_(INDEX, VAR) \
|
||||
__strong __typeof__(VAR) VAR = metamacro_concat(VAR, _weak_);
|
||||
|
||||
#if DEBUG
|
||||
#define sd_keywordify autoreleasepool {}
|
||||
#else
|
||||
#define sd_keywordify try {} @catch (...) {}
|
||||
#endif
|
||||
|
||||
#ifndef onExit
|
||||
#define onExit \
|
||||
sd_keywordify \
|
||||
__strong sd_cleanupBlock_t metamacro_concat(sd_exitBlock_, __LINE__) __attribute__((cleanup(sd_executeCleanupBlock), unused)) = ^
|
||||
#endif
|
||||
|
||||
typedef void (^sd_cleanupBlock_t)(void);
|
||||
|
||||
#if defined(__cplusplus)
|
||||
extern "C" {
|
||||
#endif
|
||||
void sd_executeCleanupBlock (__strong sd_cleanupBlock_t *block);
|
||||
#if defined(__cplusplus)
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \@keypath allows compile-time verification of key paths. Given a real object
|
||||
* receiver and key path:
|
||||
*
|
||||
* @code
|
||||
|
||||
NSString *UTF8StringPath = @keypath(str.lowercaseString.UTF8String);
|
||||
// => @"lowercaseString.UTF8String"
|
||||
|
||||
NSString *versionPath = @keypath(NSObject, version);
|
||||
// => @"version"
|
||||
|
||||
NSString *lowercaseStringPath = @keypath(NSString.new, lowercaseString);
|
||||
// => @"lowercaseString"
|
||||
|
||||
* @endcode
|
||||
*
|
||||
* ... the macro returns an \c NSString containing all but the first path
|
||||
* component or argument (e.g., @"lowercaseString.UTF8String", @"version").
|
||||
*
|
||||
* In addition to simply creating a key path, this macro ensures that the key
|
||||
* path is valid at compile-time (causing a syntax error if not), and supports
|
||||
* refactoring, such that changing the name of the property will also update any
|
||||
* uses of \@keypath.
|
||||
*/
|
||||
#define keypath(...) \
|
||||
_Pragma("clang diagnostic push") \
|
||||
_Pragma("clang diagnostic ignored \"-Warc-repeated-use-of-weak\"") \
|
||||
(NO).boolValue ? ((NSString * _Nonnull)nil) : ((NSString * _Nonnull)@(cStringKeypath(__VA_ARGS__))) \
|
||||
_Pragma("clang diagnostic pop") \
|
||||
|
||||
#define cStringKeypath(...) \
|
||||
metamacro_if_eq(1, metamacro_argcount(__VA_ARGS__))(keypath1(__VA_ARGS__))(keypath2(__VA_ARGS__))
|
||||
|
||||
#define keypath1(PATH) \
|
||||
(((void)(NO && ((void)PATH, NO)), \
|
||||
({ char *__extobjckeypath__ = strchr(# PATH, '.'); NSCAssert(__extobjckeypath__, @"Provided key path is invalid."); __extobjckeypath__ + 1; })))
|
||||
|
||||
#define keypath2(OBJ, PATH) \
|
||||
(((void)(NO && ((void)OBJ.PATH, NO)), # PATH))
|
||||
|
||||
/**
|
||||
* \@collectionKeypath allows compile-time verification of key paths across collections NSArray/NSSet etc. Given a real object
|
||||
* receiver, collection object receiver and related keypaths:
|
||||
*
|
||||
* @code
|
||||
|
||||
NSString *employeesFirstNamePath = @collectionKeypath(department.employees, Employee.new, firstName)
|
||||
// => @"employees.firstName"
|
||||
|
||||
NSString *employeesFirstNamePath = @collectionKeypath(Department.new, employees, Employee.new, firstName)
|
||||
// => @"employees.firstName"
|
||||
|
||||
* @endcode
|
||||
*
|
||||
*/
|
||||
#define collectionKeypath(...) \
|
||||
metamacro_if_eq(3, metamacro_argcount(__VA_ARGS__))(collectionKeypath3(__VA_ARGS__))(collectionKeypath4(__VA_ARGS__))
|
||||
|
||||
#define collectionKeypath3(PATH, COLLECTION_OBJECT, COLLECTION_PATH) \
|
||||
(YES).boolValue ? (NSString * _Nonnull)@((const char * _Nonnull)[[NSString stringWithFormat:@"%s.%s", cStringKeypath(PATH), cStringKeypath(COLLECTION_OBJECT, COLLECTION_PATH)] UTF8String]) : (NSString * _Nonnull)nil
|
||||
|
||||
#define collectionKeypath4(OBJ, PATH, COLLECTION_OBJECT, COLLECTION_PATH) \
|
||||
(YES).boolValue ? (NSString * _Nonnull)@((const char * _Nonnull)[[NSString stringWithFormat:@"%s.%s", cStringKeypath(OBJ, PATH), cStringKeypath(COLLECTION_OBJECT, COLLECTION_PATH)] UTF8String]) : (NSString * _Nonnull)nil
|
||||
667
Pods/SDWebImageWebPCoder/SDWebImageWebPCoder/Private/SDmetamacros.h
generated
Normal file
667
Pods/SDWebImageWebPCoder/SDWebImageWebPCoder/Private/SDmetamacros.h
generated
Normal file
@@ -0,0 +1,667 @@
|
||||
/**
|
||||
* Macros for metaprogramming
|
||||
* ExtendedC
|
||||
*
|
||||
* Copyright (C) 2012 Justin Spahr-Summers
|
||||
* Released under the MIT license
|
||||
*/
|
||||
|
||||
#ifndef EXTC_METAMACROS_H
|
||||
#define EXTC_METAMACROS_H
|
||||
|
||||
|
||||
/**
|
||||
* Executes one or more expressions (which may have a void type, such as a call
|
||||
* to a function that returns no value) and always returns true.
|
||||
*/
|
||||
#define metamacro_exprify(...) \
|
||||
((__VA_ARGS__), true)
|
||||
|
||||
/**
|
||||
* Returns a string representation of VALUE after full macro expansion.
|
||||
*/
|
||||
#define metamacro_stringify(VALUE) \
|
||||
metamacro_stringify_(VALUE)
|
||||
|
||||
/**
|
||||
* Returns A and B concatenated after full macro expansion.
|
||||
*/
|
||||
#define metamacro_concat(A, B) \
|
||||
metamacro_concat_(A, B)
|
||||
|
||||
/**
|
||||
* Returns the Nth variadic argument (starting from zero). At least
|
||||
* N + 1 variadic arguments must be given. N must be between zero and twenty,
|
||||
* inclusive.
|
||||
*/
|
||||
#define metamacro_at(N, ...) \
|
||||
metamacro_concat(metamacro_at, N)(__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* Returns the number of arguments (up to twenty) provided to the macro. At
|
||||
* least one argument must be provided.
|
||||
*
|
||||
* Inspired by P99: http://p99.gforge.inria.fr
|
||||
*/
|
||||
#define metamacro_argcount(...) \
|
||||
metamacro_at(20, __VA_ARGS__, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1)
|
||||
|
||||
/**
|
||||
* Identical to #metamacro_foreach_cxt, except that no CONTEXT argument is
|
||||
* given. Only the index and current argument will thus be passed to MACRO.
|
||||
*/
|
||||
#define metamacro_foreach(MACRO, SEP, ...) \
|
||||
metamacro_foreach_cxt(metamacro_foreach_iter, SEP, MACRO, __VA_ARGS__)
|
||||
|
||||
/**
|
||||
* For each consecutive variadic argument (up to twenty), MACRO is passed the
|
||||
* zero-based index of the current argument, CONTEXT, and then the argument
|
||||
* itself. The results of adjoining invocations of MACRO are then separated by
|
||||
* SEP.
|
||||
*
|
||||
* Inspired by P99: http://p99.gforge.inria.fr
|
||||
*/
|
||||
#define metamacro_foreach_cxt(MACRO, SEP, CONTEXT, ...) \
|
||||
metamacro_concat(metamacro_foreach_cxt, metamacro_argcount(__VA_ARGS__))(MACRO, SEP, CONTEXT, __VA_ARGS__)
|
||||
|
||||
/**
|
||||
* Identical to #metamacro_foreach_cxt. This can be used when the former would
|
||||
* fail due to recursive macro expansion.
|
||||
*/
|
||||
#define metamacro_foreach_cxt_recursive(MACRO, SEP, CONTEXT, ...) \
|
||||
metamacro_concat(metamacro_foreach_cxt_recursive, metamacro_argcount(__VA_ARGS__))(MACRO, SEP, CONTEXT, __VA_ARGS__)
|
||||
|
||||
/**
|
||||
* In consecutive order, appends each variadic argument (up to twenty) onto
|
||||
* BASE. The resulting concatenations are then separated by SEP.
|
||||
*
|
||||
* This is primarily useful to manipulate a list of macro invocations into instead
|
||||
* invoking a different, possibly related macro.
|
||||
*/
|
||||
#define metamacro_foreach_concat(BASE, SEP, ...) \
|
||||
metamacro_foreach_cxt(metamacro_foreach_concat_iter, SEP, BASE, __VA_ARGS__)
|
||||
|
||||
/**
|
||||
* Iterates COUNT times, each time invoking MACRO with the current index
|
||||
* (starting at zero) and CONTEXT. The results of adjoining invocations of MACRO
|
||||
* are then separated by SEP.
|
||||
*
|
||||
* COUNT must be an integer between zero and twenty, inclusive.
|
||||
*/
|
||||
#define metamacro_for_cxt(COUNT, MACRO, SEP, CONTEXT) \
|
||||
metamacro_concat(metamacro_for_cxt, COUNT)(MACRO, SEP, CONTEXT)
|
||||
|
||||
/**
|
||||
* Returns the first argument given. At least one argument must be provided.
|
||||
*
|
||||
* This is useful when implementing a variadic macro, where you may have only
|
||||
* one variadic argument, but no way to retrieve it (for example, because \c ...
|
||||
* always needs to match at least one argument).
|
||||
*
|
||||
* @code
|
||||
|
||||
#define varmacro(...) \
|
||||
metamacro_head(__VA_ARGS__)
|
||||
|
||||
* @endcode
|
||||
*/
|
||||
#define metamacro_head(...) \
|
||||
metamacro_head_(__VA_ARGS__, 0)
|
||||
|
||||
/**
|
||||
* Returns every argument except the first. At least two arguments must be
|
||||
* provided.
|
||||
*/
|
||||
#define metamacro_tail(...) \
|
||||
metamacro_tail_(__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* Returns the first N (up to twenty) variadic arguments as a new argument list.
|
||||
* At least N variadic arguments must be provided.
|
||||
*/
|
||||
#define metamacro_take(N, ...) \
|
||||
metamacro_concat(metamacro_take, N)(__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* Removes the first N (up to twenty) variadic arguments from the given argument
|
||||
* list. At least N variadic arguments must be provided.
|
||||
*/
|
||||
#define metamacro_drop(N, ...) \
|
||||
metamacro_concat(metamacro_drop, N)(__VA_ARGS__)
|
||||
|
||||
/**
|
||||
* Decrements VAL, which must be a number between zero and twenty, inclusive.
|
||||
*
|
||||
* This is primarily useful when dealing with indexes and counts in
|
||||
* metaprogramming.
|
||||
*/
|
||||
#define metamacro_dec(VAL) \
|
||||
metamacro_at(VAL, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19)
|
||||
|
||||
/**
|
||||
* Increments VAL, which must be a number between zero and twenty, inclusive.
|
||||
*
|
||||
* This is primarily useful when dealing with indexes and counts in
|
||||
* metaprogramming.
|
||||
*/
|
||||
#define metamacro_inc(VAL) \
|
||||
metamacro_at(VAL, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21)
|
||||
|
||||
/**
|
||||
* If A is equal to B, the next argument list is expanded; otherwise, the
|
||||
* argument list after that is expanded. A and B must be numbers between zero
|
||||
* and twenty, inclusive. Additionally, B must be greater than or equal to A.
|
||||
*
|
||||
* @code
|
||||
|
||||
// expands to true
|
||||
metamacro_if_eq(0, 0)(true)(false)
|
||||
|
||||
// expands to false
|
||||
metamacro_if_eq(0, 1)(true)(false)
|
||||
|
||||
* @endcode
|
||||
*
|
||||
* This is primarily useful when dealing with indexes and counts in
|
||||
* metaprogramming.
|
||||
*/
|
||||
#define metamacro_if_eq(A, B) \
|
||||
metamacro_concat(metamacro_if_eq, A)(B)
|
||||
|
||||
/**
|
||||
* Identical to #metamacro_if_eq. This can be used when the former would fail
|
||||
* due to recursive macro expansion.
|
||||
*/
|
||||
#define metamacro_if_eq_recursive(A, B) \
|
||||
metamacro_concat(metamacro_if_eq_recursive, A)(B)
|
||||
|
||||
/**
|
||||
* Returns 1 if N is an even number, or 0 otherwise. N must be between zero and
|
||||
* twenty, inclusive.
|
||||
*
|
||||
* For the purposes of this test, zero is considered even.
|
||||
*/
|
||||
#define metamacro_is_even(N) \
|
||||
metamacro_at(N, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1)
|
||||
|
||||
/**
|
||||
* Returns the logical NOT of B, which must be the number zero or one.
|
||||
*/
|
||||
#define metamacro_not(B) \
|
||||
metamacro_at(B, 1, 0)
|
||||
|
||||
// IMPLEMENTATION DETAILS FOLLOW!
|
||||
// Do not write code that depends on anything below this line.
|
||||
#define metamacro_stringify_(VALUE) # VALUE
|
||||
#define metamacro_concat_(A, B) A ## B
|
||||
#define metamacro_foreach_iter(INDEX, MACRO, ARG) MACRO(INDEX, ARG)
|
||||
#define metamacro_head_(FIRST, ...) FIRST
|
||||
#define metamacro_tail_(FIRST, ...) __VA_ARGS__
|
||||
#define metamacro_consume_(...)
|
||||
#define metamacro_expand_(...) __VA_ARGS__
|
||||
|
||||
// implemented from scratch so that metamacro_concat() doesn't end up nesting
|
||||
#define metamacro_foreach_concat_iter(INDEX, BASE, ARG) metamacro_foreach_concat_iter_(BASE, ARG)
|
||||
#define metamacro_foreach_concat_iter_(BASE, ARG) BASE ## ARG
|
||||
|
||||
// metamacro_at expansions
|
||||
#define metamacro_at0(...) metamacro_head(__VA_ARGS__)
|
||||
#define metamacro_at1(_0, ...) metamacro_head(__VA_ARGS__)
|
||||
#define metamacro_at2(_0, _1, ...) metamacro_head(__VA_ARGS__)
|
||||
#define metamacro_at3(_0, _1, _2, ...) metamacro_head(__VA_ARGS__)
|
||||
#define metamacro_at4(_0, _1, _2, _3, ...) metamacro_head(__VA_ARGS__)
|
||||
#define metamacro_at5(_0, _1, _2, _3, _4, ...) metamacro_head(__VA_ARGS__)
|
||||
#define metamacro_at6(_0, _1, _2, _3, _4, _5, ...) metamacro_head(__VA_ARGS__)
|
||||
#define metamacro_at7(_0, _1, _2, _3, _4, _5, _6, ...) metamacro_head(__VA_ARGS__)
|
||||
#define metamacro_at8(_0, _1, _2, _3, _4, _5, _6, _7, ...) metamacro_head(__VA_ARGS__)
|
||||
#define metamacro_at9(_0, _1, _2, _3, _4, _5, _6, _7, _8, ...) metamacro_head(__VA_ARGS__)
|
||||
#define metamacro_at10(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, ...) metamacro_head(__VA_ARGS__)
|
||||
#define metamacro_at11(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, ...) metamacro_head(__VA_ARGS__)
|
||||
#define metamacro_at12(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, ...) metamacro_head(__VA_ARGS__)
|
||||
#define metamacro_at13(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, ...) metamacro_head(__VA_ARGS__)
|
||||
#define metamacro_at14(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, ...) metamacro_head(__VA_ARGS__)
|
||||
#define metamacro_at15(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, ...) metamacro_head(__VA_ARGS__)
|
||||
#define metamacro_at16(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, ...) metamacro_head(__VA_ARGS__)
|
||||
#define metamacro_at17(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, ...) metamacro_head(__VA_ARGS__)
|
||||
#define metamacro_at18(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, ...) metamacro_head(__VA_ARGS__)
|
||||
#define metamacro_at19(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, ...) metamacro_head(__VA_ARGS__)
|
||||
#define metamacro_at20(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, ...) metamacro_head(__VA_ARGS__)
|
||||
|
||||
// metamacro_foreach_cxt expansions
|
||||
#define metamacro_foreach_cxt0(MACRO, SEP, CONTEXT)
|
||||
#define metamacro_foreach_cxt1(MACRO, SEP, CONTEXT, _0) MACRO(0, CONTEXT, _0)
|
||||
|
||||
#define metamacro_foreach_cxt2(MACRO, SEP, CONTEXT, _0, _1) \
|
||||
metamacro_foreach_cxt1(MACRO, SEP, CONTEXT, _0) \
|
||||
SEP \
|
||||
MACRO(1, CONTEXT, _1)
|
||||
|
||||
#define metamacro_foreach_cxt3(MACRO, SEP, CONTEXT, _0, _1, _2) \
|
||||
metamacro_foreach_cxt2(MACRO, SEP, CONTEXT, _0, _1) \
|
||||
SEP \
|
||||
MACRO(2, CONTEXT, _2)
|
||||
|
||||
#define metamacro_foreach_cxt4(MACRO, SEP, CONTEXT, _0, _1, _2, _3) \
|
||||
metamacro_foreach_cxt3(MACRO, SEP, CONTEXT, _0, _1, _2) \
|
||||
SEP \
|
||||
MACRO(3, CONTEXT, _3)
|
||||
|
||||
#define metamacro_foreach_cxt5(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4) \
|
||||
metamacro_foreach_cxt4(MACRO, SEP, CONTEXT, _0, _1, _2, _3) \
|
||||
SEP \
|
||||
MACRO(4, CONTEXT, _4)
|
||||
|
||||
#define metamacro_foreach_cxt6(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5) \
|
||||
metamacro_foreach_cxt5(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4) \
|
||||
SEP \
|
||||
MACRO(5, CONTEXT, _5)
|
||||
|
||||
#define metamacro_foreach_cxt7(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6) \
|
||||
metamacro_foreach_cxt6(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5) \
|
||||
SEP \
|
||||
MACRO(6, CONTEXT, _6)
|
||||
|
||||
#define metamacro_foreach_cxt8(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7) \
|
||||
metamacro_foreach_cxt7(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6) \
|
||||
SEP \
|
||||
MACRO(7, CONTEXT, _7)
|
||||
|
||||
#define metamacro_foreach_cxt9(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8) \
|
||||
metamacro_foreach_cxt8(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7) \
|
||||
SEP \
|
||||
MACRO(8, CONTEXT, _8)
|
||||
|
||||
#define metamacro_foreach_cxt10(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9) \
|
||||
metamacro_foreach_cxt9(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8) \
|
||||
SEP \
|
||||
MACRO(9, CONTEXT, _9)
|
||||
|
||||
#define metamacro_foreach_cxt11(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) \
|
||||
metamacro_foreach_cxt10(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9) \
|
||||
SEP \
|
||||
MACRO(10, CONTEXT, _10)
|
||||
|
||||
#define metamacro_foreach_cxt12(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11) \
|
||||
metamacro_foreach_cxt11(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) \
|
||||
SEP \
|
||||
MACRO(11, CONTEXT, _11)
|
||||
|
||||
#define metamacro_foreach_cxt13(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12) \
|
||||
metamacro_foreach_cxt12(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11) \
|
||||
SEP \
|
||||
MACRO(12, CONTEXT, _12)
|
||||
|
||||
#define metamacro_foreach_cxt14(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13) \
|
||||
metamacro_foreach_cxt13(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12) \
|
||||
SEP \
|
||||
MACRO(13, CONTEXT, _13)
|
||||
|
||||
#define metamacro_foreach_cxt15(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14) \
|
||||
metamacro_foreach_cxt14(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13) \
|
||||
SEP \
|
||||
MACRO(14, CONTEXT, _14)
|
||||
|
||||
#define metamacro_foreach_cxt16(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15) \
|
||||
metamacro_foreach_cxt15(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14) \
|
||||
SEP \
|
||||
MACRO(15, CONTEXT, _15)
|
||||
|
||||
#define metamacro_foreach_cxt17(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16) \
|
||||
metamacro_foreach_cxt16(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15) \
|
||||
SEP \
|
||||
MACRO(16, CONTEXT, _16)
|
||||
|
||||
#define metamacro_foreach_cxt18(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17) \
|
||||
metamacro_foreach_cxt17(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16) \
|
||||
SEP \
|
||||
MACRO(17, CONTEXT, _17)
|
||||
|
||||
#define metamacro_foreach_cxt19(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18) \
|
||||
metamacro_foreach_cxt18(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17) \
|
||||
SEP \
|
||||
MACRO(18, CONTEXT, _18)
|
||||
|
||||
#define metamacro_foreach_cxt20(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19) \
|
||||
metamacro_foreach_cxt19(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18) \
|
||||
SEP \
|
||||
MACRO(19, CONTEXT, _19)
|
||||
|
||||
// metamacro_foreach_cxt_recursive expansions
|
||||
#define metamacro_foreach_cxt_recursive0(MACRO, SEP, CONTEXT)
|
||||
#define metamacro_foreach_cxt_recursive1(MACRO, SEP, CONTEXT, _0) MACRO(0, CONTEXT, _0)
|
||||
|
||||
#define metamacro_foreach_cxt_recursive2(MACRO, SEP, CONTEXT, _0, _1) \
|
||||
metamacro_foreach_cxt_recursive1(MACRO, SEP, CONTEXT, _0) \
|
||||
SEP \
|
||||
MACRO(1, CONTEXT, _1)
|
||||
|
||||
#define metamacro_foreach_cxt_recursive3(MACRO, SEP, CONTEXT, _0, _1, _2) \
|
||||
metamacro_foreach_cxt_recursive2(MACRO, SEP, CONTEXT, _0, _1) \
|
||||
SEP \
|
||||
MACRO(2, CONTEXT, _2)
|
||||
|
||||
#define metamacro_foreach_cxt_recursive4(MACRO, SEP, CONTEXT, _0, _1, _2, _3) \
|
||||
metamacro_foreach_cxt_recursive3(MACRO, SEP, CONTEXT, _0, _1, _2) \
|
||||
SEP \
|
||||
MACRO(3, CONTEXT, _3)
|
||||
|
||||
#define metamacro_foreach_cxt_recursive5(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4) \
|
||||
metamacro_foreach_cxt_recursive4(MACRO, SEP, CONTEXT, _0, _1, _2, _3) \
|
||||
SEP \
|
||||
MACRO(4, CONTEXT, _4)
|
||||
|
||||
#define metamacro_foreach_cxt_recursive6(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5) \
|
||||
metamacro_foreach_cxt_recursive5(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4) \
|
||||
SEP \
|
||||
MACRO(5, CONTEXT, _5)
|
||||
|
||||
#define metamacro_foreach_cxt_recursive7(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6) \
|
||||
metamacro_foreach_cxt_recursive6(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5) \
|
||||
SEP \
|
||||
MACRO(6, CONTEXT, _6)
|
||||
|
||||
#define metamacro_foreach_cxt_recursive8(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7) \
|
||||
metamacro_foreach_cxt_recursive7(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6) \
|
||||
SEP \
|
||||
MACRO(7, CONTEXT, _7)
|
||||
|
||||
#define metamacro_foreach_cxt_recursive9(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8) \
|
||||
metamacro_foreach_cxt_recursive8(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7) \
|
||||
SEP \
|
||||
MACRO(8, CONTEXT, _8)
|
||||
|
||||
#define metamacro_foreach_cxt_recursive10(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9) \
|
||||
metamacro_foreach_cxt_recursive9(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8) \
|
||||
SEP \
|
||||
MACRO(9, CONTEXT, _9)
|
||||
|
||||
#define metamacro_foreach_cxt_recursive11(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) \
|
||||
metamacro_foreach_cxt_recursive10(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9) \
|
||||
SEP \
|
||||
MACRO(10, CONTEXT, _10)
|
||||
|
||||
#define metamacro_foreach_cxt_recursive12(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11) \
|
||||
metamacro_foreach_cxt_recursive11(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) \
|
||||
SEP \
|
||||
MACRO(11, CONTEXT, _11)
|
||||
|
||||
#define metamacro_foreach_cxt_recursive13(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12) \
|
||||
metamacro_foreach_cxt_recursive12(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11) \
|
||||
SEP \
|
||||
MACRO(12, CONTEXT, _12)
|
||||
|
||||
#define metamacro_foreach_cxt_recursive14(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13) \
|
||||
metamacro_foreach_cxt_recursive13(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12) \
|
||||
SEP \
|
||||
MACRO(13, CONTEXT, _13)
|
||||
|
||||
#define metamacro_foreach_cxt_recursive15(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14) \
|
||||
metamacro_foreach_cxt_recursive14(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13) \
|
||||
SEP \
|
||||
MACRO(14, CONTEXT, _14)
|
||||
|
||||
#define metamacro_foreach_cxt_recursive16(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15) \
|
||||
metamacro_foreach_cxt_recursive15(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14) \
|
||||
SEP \
|
||||
MACRO(15, CONTEXT, _15)
|
||||
|
||||
#define metamacro_foreach_cxt_recursive17(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16) \
|
||||
metamacro_foreach_cxt_recursive16(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15) \
|
||||
SEP \
|
||||
MACRO(16, CONTEXT, _16)
|
||||
|
||||
#define metamacro_foreach_cxt_recursive18(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17) \
|
||||
metamacro_foreach_cxt_recursive17(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16) \
|
||||
SEP \
|
||||
MACRO(17, CONTEXT, _17)
|
||||
|
||||
#define metamacro_foreach_cxt_recursive19(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18) \
|
||||
metamacro_foreach_cxt_recursive18(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17) \
|
||||
SEP \
|
||||
MACRO(18, CONTEXT, _18)
|
||||
|
||||
#define metamacro_foreach_cxt_recursive20(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19) \
|
||||
metamacro_foreach_cxt_recursive19(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18) \
|
||||
SEP \
|
||||
MACRO(19, CONTEXT, _19)
|
||||
|
||||
// metamacro_for_cxt expansions
|
||||
#define metamacro_for_cxt0(MACRO, SEP, CONTEXT)
|
||||
#define metamacro_for_cxt1(MACRO, SEP, CONTEXT) MACRO(0, CONTEXT)
|
||||
|
||||
#define metamacro_for_cxt2(MACRO, SEP, CONTEXT) \
|
||||
metamacro_for_cxt1(MACRO, SEP, CONTEXT) \
|
||||
SEP \
|
||||
MACRO(1, CONTEXT)
|
||||
|
||||
#define metamacro_for_cxt3(MACRO, SEP, CONTEXT) \
|
||||
metamacro_for_cxt2(MACRO, SEP, CONTEXT) \
|
||||
SEP \
|
||||
MACRO(2, CONTEXT)
|
||||
|
||||
#define metamacro_for_cxt4(MACRO, SEP, CONTEXT) \
|
||||
metamacro_for_cxt3(MACRO, SEP, CONTEXT) \
|
||||
SEP \
|
||||
MACRO(3, CONTEXT)
|
||||
|
||||
#define metamacro_for_cxt5(MACRO, SEP, CONTEXT) \
|
||||
metamacro_for_cxt4(MACRO, SEP, CONTEXT) \
|
||||
SEP \
|
||||
MACRO(4, CONTEXT)
|
||||
|
||||
#define metamacro_for_cxt6(MACRO, SEP, CONTEXT) \
|
||||
metamacro_for_cxt5(MACRO, SEP, CONTEXT) \
|
||||
SEP \
|
||||
MACRO(5, CONTEXT)
|
||||
|
||||
#define metamacro_for_cxt7(MACRO, SEP, CONTEXT) \
|
||||
metamacro_for_cxt6(MACRO, SEP, CONTEXT) \
|
||||
SEP \
|
||||
MACRO(6, CONTEXT)
|
||||
|
||||
#define metamacro_for_cxt8(MACRO, SEP, CONTEXT) \
|
||||
metamacro_for_cxt7(MACRO, SEP, CONTEXT) \
|
||||
SEP \
|
||||
MACRO(7, CONTEXT)
|
||||
|
||||
#define metamacro_for_cxt9(MACRO, SEP, CONTEXT) \
|
||||
metamacro_for_cxt8(MACRO, SEP, CONTEXT) \
|
||||
SEP \
|
||||
MACRO(8, CONTEXT)
|
||||
|
||||
#define metamacro_for_cxt10(MACRO, SEP, CONTEXT) \
|
||||
metamacro_for_cxt9(MACRO, SEP, CONTEXT) \
|
||||
SEP \
|
||||
MACRO(9, CONTEXT)
|
||||
|
||||
#define metamacro_for_cxt11(MACRO, SEP, CONTEXT) \
|
||||
metamacro_for_cxt10(MACRO, SEP, CONTEXT) \
|
||||
SEP \
|
||||
MACRO(10, CONTEXT)
|
||||
|
||||
#define metamacro_for_cxt12(MACRO, SEP, CONTEXT) \
|
||||
metamacro_for_cxt11(MACRO, SEP, CONTEXT) \
|
||||
SEP \
|
||||
MACRO(11, CONTEXT)
|
||||
|
||||
#define metamacro_for_cxt13(MACRO, SEP, CONTEXT) \
|
||||
metamacro_for_cxt12(MACRO, SEP, CONTEXT) \
|
||||
SEP \
|
||||
MACRO(12, CONTEXT)
|
||||
|
||||
#define metamacro_for_cxt14(MACRO, SEP, CONTEXT) \
|
||||
metamacro_for_cxt13(MACRO, SEP, CONTEXT) \
|
||||
SEP \
|
||||
MACRO(13, CONTEXT)
|
||||
|
||||
#define metamacro_for_cxt15(MACRO, SEP, CONTEXT) \
|
||||
metamacro_for_cxt14(MACRO, SEP, CONTEXT) \
|
||||
SEP \
|
||||
MACRO(14, CONTEXT)
|
||||
|
||||
#define metamacro_for_cxt16(MACRO, SEP, CONTEXT) \
|
||||
metamacro_for_cxt15(MACRO, SEP, CONTEXT) \
|
||||
SEP \
|
||||
MACRO(15, CONTEXT)
|
||||
|
||||
#define metamacro_for_cxt17(MACRO, SEP, CONTEXT) \
|
||||
metamacro_for_cxt16(MACRO, SEP, CONTEXT) \
|
||||
SEP \
|
||||
MACRO(16, CONTEXT)
|
||||
|
||||
#define metamacro_for_cxt18(MACRO, SEP, CONTEXT) \
|
||||
metamacro_for_cxt17(MACRO, SEP, CONTEXT) \
|
||||
SEP \
|
||||
MACRO(17, CONTEXT)
|
||||
|
||||
#define metamacro_for_cxt19(MACRO, SEP, CONTEXT) \
|
||||
metamacro_for_cxt18(MACRO, SEP, CONTEXT) \
|
||||
SEP \
|
||||
MACRO(18, CONTEXT)
|
||||
|
||||
#define metamacro_for_cxt20(MACRO, SEP, CONTEXT) \
|
||||
metamacro_for_cxt19(MACRO, SEP, CONTEXT) \
|
||||
SEP \
|
||||
MACRO(19, CONTEXT)
|
||||
|
||||
// metamacro_if_eq expansions
|
||||
#define metamacro_if_eq0(VALUE) \
|
||||
metamacro_concat(metamacro_if_eq0_, VALUE)
|
||||
|
||||
#define metamacro_if_eq0_0(...) __VA_ARGS__ metamacro_consume_
|
||||
#define metamacro_if_eq0_1(...) metamacro_expand_
|
||||
#define metamacro_if_eq0_2(...) metamacro_expand_
|
||||
#define metamacro_if_eq0_3(...) metamacro_expand_
|
||||
#define metamacro_if_eq0_4(...) metamacro_expand_
|
||||
#define metamacro_if_eq0_5(...) metamacro_expand_
|
||||
#define metamacro_if_eq0_6(...) metamacro_expand_
|
||||
#define metamacro_if_eq0_7(...) metamacro_expand_
|
||||
#define metamacro_if_eq0_8(...) metamacro_expand_
|
||||
#define metamacro_if_eq0_9(...) metamacro_expand_
|
||||
#define metamacro_if_eq0_10(...) metamacro_expand_
|
||||
#define metamacro_if_eq0_11(...) metamacro_expand_
|
||||
#define metamacro_if_eq0_12(...) metamacro_expand_
|
||||
#define metamacro_if_eq0_13(...) metamacro_expand_
|
||||
#define metamacro_if_eq0_14(...) metamacro_expand_
|
||||
#define metamacro_if_eq0_15(...) metamacro_expand_
|
||||
#define metamacro_if_eq0_16(...) metamacro_expand_
|
||||
#define metamacro_if_eq0_17(...) metamacro_expand_
|
||||
#define metamacro_if_eq0_18(...) metamacro_expand_
|
||||
#define metamacro_if_eq0_19(...) metamacro_expand_
|
||||
#define metamacro_if_eq0_20(...) metamacro_expand_
|
||||
|
||||
#define metamacro_if_eq1(VALUE) metamacro_if_eq0(metamacro_dec(VALUE))
|
||||
#define metamacro_if_eq2(VALUE) metamacro_if_eq1(metamacro_dec(VALUE))
|
||||
#define metamacro_if_eq3(VALUE) metamacro_if_eq2(metamacro_dec(VALUE))
|
||||
#define metamacro_if_eq4(VALUE) metamacro_if_eq3(metamacro_dec(VALUE))
|
||||
#define metamacro_if_eq5(VALUE) metamacro_if_eq4(metamacro_dec(VALUE))
|
||||
#define metamacro_if_eq6(VALUE) metamacro_if_eq5(metamacro_dec(VALUE))
|
||||
#define metamacro_if_eq7(VALUE) metamacro_if_eq6(metamacro_dec(VALUE))
|
||||
#define metamacro_if_eq8(VALUE) metamacro_if_eq7(metamacro_dec(VALUE))
|
||||
#define metamacro_if_eq9(VALUE) metamacro_if_eq8(metamacro_dec(VALUE))
|
||||
#define metamacro_if_eq10(VALUE) metamacro_if_eq9(metamacro_dec(VALUE))
|
||||
#define metamacro_if_eq11(VALUE) metamacro_if_eq10(metamacro_dec(VALUE))
|
||||
#define metamacro_if_eq12(VALUE) metamacro_if_eq11(metamacro_dec(VALUE))
|
||||
#define metamacro_if_eq13(VALUE) metamacro_if_eq12(metamacro_dec(VALUE))
|
||||
#define metamacro_if_eq14(VALUE) metamacro_if_eq13(metamacro_dec(VALUE))
|
||||
#define metamacro_if_eq15(VALUE) metamacro_if_eq14(metamacro_dec(VALUE))
|
||||
#define metamacro_if_eq16(VALUE) metamacro_if_eq15(metamacro_dec(VALUE))
|
||||
#define metamacro_if_eq17(VALUE) metamacro_if_eq16(metamacro_dec(VALUE))
|
||||
#define metamacro_if_eq18(VALUE) metamacro_if_eq17(metamacro_dec(VALUE))
|
||||
#define metamacro_if_eq19(VALUE) metamacro_if_eq18(metamacro_dec(VALUE))
|
||||
#define metamacro_if_eq20(VALUE) metamacro_if_eq19(metamacro_dec(VALUE))
|
||||
|
||||
// metamacro_if_eq_recursive expansions
|
||||
#define metamacro_if_eq_recursive0(VALUE) \
|
||||
metamacro_concat(metamacro_if_eq_recursive0_, VALUE)
|
||||
|
||||
#define metamacro_if_eq_recursive0_0(...) __VA_ARGS__ metamacro_consume_
|
||||
#define metamacro_if_eq_recursive0_1(...) metamacro_expand_
|
||||
#define metamacro_if_eq_recursive0_2(...) metamacro_expand_
|
||||
#define metamacro_if_eq_recursive0_3(...) metamacro_expand_
|
||||
#define metamacro_if_eq_recursive0_4(...) metamacro_expand_
|
||||
#define metamacro_if_eq_recursive0_5(...) metamacro_expand_
|
||||
#define metamacro_if_eq_recursive0_6(...) metamacro_expand_
|
||||
#define metamacro_if_eq_recursive0_7(...) metamacro_expand_
|
||||
#define metamacro_if_eq_recursive0_8(...) metamacro_expand_
|
||||
#define metamacro_if_eq_recursive0_9(...) metamacro_expand_
|
||||
#define metamacro_if_eq_recursive0_10(...) metamacro_expand_
|
||||
#define metamacro_if_eq_recursive0_11(...) metamacro_expand_
|
||||
#define metamacro_if_eq_recursive0_12(...) metamacro_expand_
|
||||
#define metamacro_if_eq_recursive0_13(...) metamacro_expand_
|
||||
#define metamacro_if_eq_recursive0_14(...) metamacro_expand_
|
||||
#define metamacro_if_eq_recursive0_15(...) metamacro_expand_
|
||||
#define metamacro_if_eq_recursive0_16(...) metamacro_expand_
|
||||
#define metamacro_if_eq_recursive0_17(...) metamacro_expand_
|
||||
#define metamacro_if_eq_recursive0_18(...) metamacro_expand_
|
||||
#define metamacro_if_eq_recursive0_19(...) metamacro_expand_
|
||||
#define metamacro_if_eq_recursive0_20(...) metamacro_expand_
|
||||
|
||||
#define metamacro_if_eq_recursive1(VALUE) metamacro_if_eq_recursive0(metamacro_dec(VALUE))
|
||||
#define metamacro_if_eq_recursive2(VALUE) metamacro_if_eq_recursive1(metamacro_dec(VALUE))
|
||||
#define metamacro_if_eq_recursive3(VALUE) metamacro_if_eq_recursive2(metamacro_dec(VALUE))
|
||||
#define metamacro_if_eq_recursive4(VALUE) metamacro_if_eq_recursive3(metamacro_dec(VALUE))
|
||||
#define metamacro_if_eq_recursive5(VALUE) metamacro_if_eq_recursive4(metamacro_dec(VALUE))
|
||||
#define metamacro_if_eq_recursive6(VALUE) metamacro_if_eq_recursive5(metamacro_dec(VALUE))
|
||||
#define metamacro_if_eq_recursive7(VALUE) metamacro_if_eq_recursive6(metamacro_dec(VALUE))
|
||||
#define metamacro_if_eq_recursive8(VALUE) metamacro_if_eq_recursive7(metamacro_dec(VALUE))
|
||||
#define metamacro_if_eq_recursive9(VALUE) metamacro_if_eq_recursive8(metamacro_dec(VALUE))
|
||||
#define metamacro_if_eq_recursive10(VALUE) metamacro_if_eq_recursive9(metamacro_dec(VALUE))
|
||||
#define metamacro_if_eq_recursive11(VALUE) metamacro_if_eq_recursive10(metamacro_dec(VALUE))
|
||||
#define metamacro_if_eq_recursive12(VALUE) metamacro_if_eq_recursive11(metamacro_dec(VALUE))
|
||||
#define metamacro_if_eq_recursive13(VALUE) metamacro_if_eq_recursive12(metamacro_dec(VALUE))
|
||||
#define metamacro_if_eq_recursive14(VALUE) metamacro_if_eq_recursive13(metamacro_dec(VALUE))
|
||||
#define metamacro_if_eq_recursive15(VALUE) metamacro_if_eq_recursive14(metamacro_dec(VALUE))
|
||||
#define metamacro_if_eq_recursive16(VALUE) metamacro_if_eq_recursive15(metamacro_dec(VALUE))
|
||||
#define metamacro_if_eq_recursive17(VALUE) metamacro_if_eq_recursive16(metamacro_dec(VALUE))
|
||||
#define metamacro_if_eq_recursive18(VALUE) metamacro_if_eq_recursive17(metamacro_dec(VALUE))
|
||||
#define metamacro_if_eq_recursive19(VALUE) metamacro_if_eq_recursive18(metamacro_dec(VALUE))
|
||||
#define metamacro_if_eq_recursive20(VALUE) metamacro_if_eq_recursive19(metamacro_dec(VALUE))
|
||||
|
||||
// metamacro_take expansions
|
||||
#define metamacro_take0(...)
|
||||
#define metamacro_take1(...) metamacro_head(__VA_ARGS__)
|
||||
#define metamacro_take2(...) metamacro_head(__VA_ARGS__), metamacro_take1(metamacro_tail(__VA_ARGS__))
|
||||
#define metamacro_take3(...) metamacro_head(__VA_ARGS__), metamacro_take2(metamacro_tail(__VA_ARGS__))
|
||||
#define metamacro_take4(...) metamacro_head(__VA_ARGS__), metamacro_take3(metamacro_tail(__VA_ARGS__))
|
||||
#define metamacro_take5(...) metamacro_head(__VA_ARGS__), metamacro_take4(metamacro_tail(__VA_ARGS__))
|
||||
#define metamacro_take6(...) metamacro_head(__VA_ARGS__), metamacro_take5(metamacro_tail(__VA_ARGS__))
|
||||
#define metamacro_take7(...) metamacro_head(__VA_ARGS__), metamacro_take6(metamacro_tail(__VA_ARGS__))
|
||||
#define metamacro_take8(...) metamacro_head(__VA_ARGS__), metamacro_take7(metamacro_tail(__VA_ARGS__))
|
||||
#define metamacro_take9(...) metamacro_head(__VA_ARGS__), metamacro_take8(metamacro_tail(__VA_ARGS__))
|
||||
#define metamacro_take10(...) metamacro_head(__VA_ARGS__), metamacro_take9(metamacro_tail(__VA_ARGS__))
|
||||
#define metamacro_take11(...) metamacro_head(__VA_ARGS__), metamacro_take10(metamacro_tail(__VA_ARGS__))
|
||||
#define metamacro_take12(...) metamacro_head(__VA_ARGS__), metamacro_take11(metamacro_tail(__VA_ARGS__))
|
||||
#define metamacro_take13(...) metamacro_head(__VA_ARGS__), metamacro_take12(metamacro_tail(__VA_ARGS__))
|
||||
#define metamacro_take14(...) metamacro_head(__VA_ARGS__), metamacro_take13(metamacro_tail(__VA_ARGS__))
|
||||
#define metamacro_take15(...) metamacro_head(__VA_ARGS__), metamacro_take14(metamacro_tail(__VA_ARGS__))
|
||||
#define metamacro_take16(...) metamacro_head(__VA_ARGS__), metamacro_take15(metamacro_tail(__VA_ARGS__))
|
||||
#define metamacro_take17(...) metamacro_head(__VA_ARGS__), metamacro_take16(metamacro_tail(__VA_ARGS__))
|
||||
#define metamacro_take18(...) metamacro_head(__VA_ARGS__), metamacro_take17(metamacro_tail(__VA_ARGS__))
|
||||
#define metamacro_take19(...) metamacro_head(__VA_ARGS__), metamacro_take18(metamacro_tail(__VA_ARGS__))
|
||||
#define metamacro_take20(...) metamacro_head(__VA_ARGS__), metamacro_take19(metamacro_tail(__VA_ARGS__))
|
||||
|
||||
// metamacro_drop expansions
|
||||
#define metamacro_drop0(...) __VA_ARGS__
|
||||
#define metamacro_drop1(...) metamacro_tail(__VA_ARGS__)
|
||||
#define metamacro_drop2(...) metamacro_drop1(metamacro_tail(__VA_ARGS__))
|
||||
#define metamacro_drop3(...) metamacro_drop2(metamacro_tail(__VA_ARGS__))
|
||||
#define metamacro_drop4(...) metamacro_drop3(metamacro_tail(__VA_ARGS__))
|
||||
#define metamacro_drop5(...) metamacro_drop4(metamacro_tail(__VA_ARGS__))
|
||||
#define metamacro_drop6(...) metamacro_drop5(metamacro_tail(__VA_ARGS__))
|
||||
#define metamacro_drop7(...) metamacro_drop6(metamacro_tail(__VA_ARGS__))
|
||||
#define metamacro_drop8(...) metamacro_drop7(metamacro_tail(__VA_ARGS__))
|
||||
#define metamacro_drop9(...) metamacro_drop8(metamacro_tail(__VA_ARGS__))
|
||||
#define metamacro_drop10(...) metamacro_drop9(metamacro_tail(__VA_ARGS__))
|
||||
#define metamacro_drop11(...) metamacro_drop10(metamacro_tail(__VA_ARGS__))
|
||||
#define metamacro_drop12(...) metamacro_drop11(metamacro_tail(__VA_ARGS__))
|
||||
#define metamacro_drop13(...) metamacro_drop12(metamacro_tail(__VA_ARGS__))
|
||||
#define metamacro_drop14(...) metamacro_drop13(metamacro_tail(__VA_ARGS__))
|
||||
#define metamacro_drop15(...) metamacro_drop14(metamacro_tail(__VA_ARGS__))
|
||||
#define metamacro_drop16(...) metamacro_drop15(metamacro_tail(__VA_ARGS__))
|
||||
#define metamacro_drop17(...) metamacro_drop16(metamacro_tail(__VA_ARGS__))
|
||||
#define metamacro_drop18(...) metamacro_drop17(metamacro_tail(__VA_ARGS__))
|
||||
#define metamacro_drop19(...) metamacro_drop18(metamacro_tail(__VA_ARGS__))
|
||||
#define metamacro_drop20(...) metamacro_drop19(metamacro_tail(__VA_ARGS__))
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user