├── OKObserver
├── Assets
│ └── .gitkeep
└── Classes
│ ├── .gitkeep
│ ├── NSObject+ObservingKeypath.h
│ ├── OKObserver.h
│ ├── NSObject+ObservingKeypath.m
│ ├── EXTKeyPathCoding.h
│ ├── OKObserver.m
│ └── metamacros.h
├── _Pods.xcodeproj
├── Example
├── Tests
│ ├── en.lproj
│ │ └── InfoPlist.strings
│ ├── Tests-Prefix.pch
│ ├── Tests.m
│ └── Tests-Info.plist
├── OKObserver
│ ├── en.lproj
│ │ └── InfoPlist.strings
│ ├── XXObject.m
│ ├── OKViewController.h
│ ├── OKAppDelegate.h
│ ├── XXObject.h
│ ├── OKObserver-Prefix.pch
│ ├── main.m
│ ├── OKViewController.m
│ ├── Images.xcassets
│ │ ├── AppIcon.appiconset
│ │ │ └── Contents.json
│ │ └── LaunchImage.launchimage
│ │ │ └── Contents.json
│ ├── OKObserver-Info.plist
│ ├── Main.storyboard
│ └── OKAppDelegate.m
├── OKObserver.xcodeproj
│ ├── project.xcworkspace
│ │ └── contents.xcworkspacedata
│ ├── xcshareddata
│ │ └── xcschemes
│ │ │ └── OKObserver-Example.xcscheme
│ └── project.pbxproj
├── Podfile
├── OKObserver.xcworkspace
│ └── contents.xcworkspacedata
└── Podfile.lock
├── .gitattributes
├── fastlane
├── Appfile
├── README.md
├── Fastfile
└── actions
│ ├── sync_build_number_to_git.rb
│ └── git_commit_all.rb
├── .travis.yml
├── .gitignore
├── OKObserver.podspec
├── LICENSE
└── README.md
/OKObserver/Assets/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/OKObserver/Classes/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/_Pods.xcodeproj:
--------------------------------------------------------------------------------
1 | Example/Pods/Pods.xcodeproj
--------------------------------------------------------------------------------
/Example/Tests/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
3 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | *.c linguist-language=Objective-C
2 | *.h linguist-language=Objective-C
3 |
4 |
--------------------------------------------------------------------------------
/Example/OKObserver/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
3 |
--------------------------------------------------------------------------------
/Example/Tests/Tests-Prefix.pch:
--------------------------------------------------------------------------------
1 | // The contents of this file are implicitly included at the beginning of every test case source file.
2 |
3 | #ifdef __OBJC__
4 |
5 | @import Specta;
6 | @import Expecta;
7 |
8 | #endif
9 |
--------------------------------------------------------------------------------
/Example/OKObserver.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Example/Podfile:
--------------------------------------------------------------------------------
1 | use_frameworks!
2 |
3 | target 'OKObserver_Example' do
4 | pod 'OKObserver', :path => '../'
5 |
6 | target 'OKObserver_Tests' do
7 | inherit! :search_paths
8 |
9 | pod 'Specta'
10 | pod 'Expecta'
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/Example/OKObserver/XXObject.m:
--------------------------------------------------------------------------------
1 | //
2 | // XXObject.m
3 | // Tied
4 | //
5 | // Created by Draveness on 5/18/16.
6 | // Copyright © 2016 Draveness. All rights reserved.
7 | //
8 |
9 | #import "XXObject.h"
10 |
11 | @implementation XXObject
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/Example/OKObserver/OKViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // OKViewController.h
3 | // OKObserver
4 | //
5 | // Created by Draveness on 05/18/2016.
6 | // Copyright (c) 2016 Draveness. All rights reserved.
7 | //
8 |
9 | @import UIKit;
10 |
11 | @interface OKViewController : UIViewController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/Example/OKObserver.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/OKObserver/Classes/NSObject+ObservingKeypath.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSObject+ObservingKeypath.h
3 | // Pods
4 | //
5 | // Created by Draveness on 5/18/16.
6 | //
7 | //
8 |
9 | #import
10 |
11 | @interface NSObject (ObservingKeypath)
12 |
13 | @property (nonatomic, strong) NSMutableArray *observingKeypath;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/fastlane/Appfile:
--------------------------------------------------------------------------------
1 | app_identifier "" # The bundle identifier of your app
2 | apple_id "" # Your Apple email address
3 |
4 | team_id "[[DEV_PORTAL_TEAM_ID]]" # Developer Portal Team ID
5 |
6 | # you can even provide different app identifiers, Apple IDs and team names per lane:
7 | # More information: https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Appfile.md
8 |
--------------------------------------------------------------------------------
/Example/OKObserver/OKAppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // OKAppDelegate.h
3 | // OKObserver
4 | //
5 | // Created by Draveness on 05/18/2016.
6 | // Copyright (c) 2016 Draveness. All rights reserved.
7 | //
8 |
9 | @import UIKit;
10 |
11 | @interface OKAppDelegate : UIResponder
12 |
13 | @property (strong, nonatomic) UIWindow *window;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/Example/OKObserver/XXObject.h:
--------------------------------------------------------------------------------
1 | //
2 | // XXObject.h
3 | // Tied
4 | //
5 | // Created by Draveness on 5/18/16.
6 | // Copyright © 2016 Draveness. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface XXObject : NSObject
12 |
13 | @property (nonatomic, assign) CGFloat number;
14 | @property (nonatomic, strong) UIColor *color;
15 |
16 | @end
17 |
--------------------------------------------------------------------------------
/Example/OKObserver/OKObserver-Prefix.pch:
--------------------------------------------------------------------------------
1 | //
2 | // Prefix header
3 | //
4 | // The contents of this file are implicitly included at the beginning of every source file.
5 | //
6 |
7 | #import
8 |
9 | #ifndef __IPHONE_5_0
10 | #warning "This project uses features only available in iOS SDK 5.0 and later."
11 | #endif
12 |
13 | #ifdef __OBJC__
14 | @import UIKit;
15 | @import Foundation;
16 | #endif
17 |
--------------------------------------------------------------------------------
/Example/OKObserver/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // OKObserver
4 | //
5 | // Created by Draveness on 05/18/2016.
6 | // Copyright (c) 2016 Draveness. All rights reserved.
7 | //
8 |
9 | @import UIKit;
10 | #import "OKAppDelegate.h"
11 |
12 | int main(int argc, char * argv[])
13 | {
14 | @autoreleasepool {
15 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([OKAppDelegate class]));
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | # references:
2 | # * http://www.objc.io/issue-6/travis-ci.html
3 | # * https://github.com/supermarin/xcpretty#usage
4 |
5 | language: objective-c
6 | podfile: Example/Podfile
7 | osx_image: xcode7.3
8 | before_install:
9 | - gem install cocoapods # Since Travis is not always on latest version
10 | - pod install --project-directory=Example
11 | script:
12 | - set -o pipefail && xcodebuild test -workspace Example/OKObserver.xcworkspace -scheme OKObserver-Example -sdk iphonesimulator ONLY_ACTIVE_ARCH=NO | xcpretty
13 | - pod lib lint
14 |
--------------------------------------------------------------------------------
/Example/Podfile.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - Expecta (1.0.5)
3 | - OKObserver (0.1.0)
4 | - Specta (1.0.5)
5 |
6 | DEPENDENCIES:
7 | - Expecta
8 | - OKObserver (from `../`)
9 | - Specta
10 |
11 | EXTERNAL SOURCES:
12 | OKObserver:
13 | :path: "../"
14 |
15 | SPEC CHECKSUMS:
16 | Expecta: e1c022fcd33910b6be89c291d2775b3fe27a89fe
17 | OKObserver: d4f94b85e09182414624592066b2030a71108ffa
18 | Specta: ac94d110b865115fe60ff2c6d7281053c6f8e8a2
19 |
20 | PODFILE CHECKSUM: 4df3c55e5f1e167d3c1430091b699e47421a29e7
21 |
22 | COCOAPODS: 1.0.0
23 |
--------------------------------------------------------------------------------
/fastlane/README.md:
--------------------------------------------------------------------------------
1 | fastlane documentation
2 | ================
3 | # Installation
4 | ```
5 | sudo gem install fastlane
6 | ```
7 | # Available Actions
8 | ### release
9 | ```
10 | fastlane release
11 | ```
12 | Release new version
13 |
14 | ----
15 |
16 | This README.md is auto-generated and will be re-generated every time to run [fastlane](https://fastlane.tools).
17 | More information about fastlane can be found on [https://fastlane.tools](https://fastlane.tools).
18 | The documentation of fastlane can be found on [GitHub](https://github.com/fastlane/fastlane/tree/master/fastlane).
--------------------------------------------------------------------------------
/OKObserver/Classes/OKObserver.h:
--------------------------------------------------------------------------------
1 | //
2 | // OKObserver.h
3 | // Pods
4 | //
5 | // Created by Draveness on 5/18/16.
6 | //
7 | //
8 |
9 | #import
10 | #import "EXTKeyPathCoding.h"
11 |
12 | #define OKObserve(OBSERVEE, KEYPATH) [OKObserver observerWithObservee:OBSERVEE keypath:@keypath(OBSERVEE, KEYPATH)]
13 |
14 | @interface OKObserver : NSObject
15 |
16 | - (instancetype)initWithObservee:(id)observee keypath:(NSString *)keypath;
17 |
18 | + (OKObserver *)observerWithObservee:(id)observee keypath:(NSString *)keypath;
19 |
20 | - (void)whenUpdated:(void(^)(id newValue))updateBlock;
21 |
22 | - (void)update:(OKObserver *)observer;
23 |
24 | @end
25 |
--------------------------------------------------------------------------------
/Example/Tests/Tests.m:
--------------------------------------------------------------------------------
1 | //
2 | // OKObserverTests.m
3 | // OKObserverTests
4 | //
5 | // Created by Draveness on 05/18/2016.
6 | // Copyright (c) 2016 Draveness. All rights reserved.
7 | //
8 |
9 | // https://github.com/Specta/Specta
10 |
11 | SpecBegin(InitialSpecs)
12 |
13 | describe(@"these will pass", ^{
14 |
15 | it(@"can do maths", ^{
16 | expect(1).beLessThan(23);
17 | });
18 |
19 | it(@"can read", ^{
20 | expect(@"team").toNot.contain(@"I");
21 | });
22 |
23 | it(@"will wait and succeed", ^{
24 | waitUntil(^(DoneCallback done) {
25 | done();
26 | });
27 | });
28 | });
29 |
30 | SpecEnd
31 |
32 |
--------------------------------------------------------------------------------
/Example/Tests/Tests-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundlePackageType
14 | BNDL
15 | CFBundleShortVersionString
16 | 1.0
17 | CFBundleSignature
18 | ????
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # OS X
2 | .DS_Store
3 |
4 | # Xcode
5 | build/
6 | *.pbxuser
7 | !default.pbxuser
8 | *.mode1v3
9 | !default.mode1v3
10 | *.mode2v3
11 | !default.mode2v3
12 | *.perspectivev3
13 | !default.perspectivev3
14 | xcuserdata/
15 | *.xccheckout
16 | profile
17 | *.moved-aside
18 | DerivedData
19 | *.hmap
20 | *.ipa
21 |
22 | # Bundler
23 | .bundle
24 |
25 | Carthage
26 | # We recommend against adding the Pods directory to your .gitignore. However
27 | # you should judge for yourself, the pros and cons are mentioned at:
28 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
29 | #
30 | # Note: if you ignore the Pods directory, make sure to uncomment
31 | # `pod install` in .travis.yml
32 | #
33 | Pods/
34 |
35 | # Fastlane
36 | fastlane/report.xml
37 |
--------------------------------------------------------------------------------
/fastlane/Fastfile:
--------------------------------------------------------------------------------
1 | fastlane_version "1.89.0"
2 |
3 | default_platform :ios
4 |
5 | # Fastfile
6 | desc "Release new version"
7 | lane :release do |options|
8 | target_version = options[:version]
9 | raise "The version is missed." if target_version.nil?
10 | ensure_git_branch
11 | ensure_git_status_clean
12 | # scan
13 |
14 | sync_build_number_to_git
15 | increment_version_number(version_number: target_version)
16 |
17 | version_bump_podspec(path: "OKObserver.podspec",
18 | version_number: target_version)
19 | git_commit_all(message: "Bump version to #{target_version}")
20 | add_git_tag tag: target_version
21 | push_to_git_remote
22 | pod_push
23 | end
24 |
25 |
--------------------------------------------------------------------------------
/Example/OKObserver/OKViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // OKViewController.m
3 | // OKObserver
4 | //
5 | // Created by Draveness on 05/18/2016.
6 | // Copyright (c) 2016 Draveness. All rights reserved.
7 | //
8 |
9 | #import "OKViewController.h"
10 | #import "OKObserver.h"
11 | #import "XXObject.h"
12 |
13 | @interface OKViewController ()
14 |
15 | @end
16 |
17 | @implementation OKViewController
18 |
19 | - (void)viewDidLoad {
20 | [super viewDidLoad];
21 | XXObject *object = [XXObject new];
22 | object.color = [UIColor redColor];
23 | [OKObserve(object, color) update:OKObserve(self, view.backgroundColor)];
24 |
25 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
26 | object.color = [UIColor yellowColor];
27 | });
28 | }
29 |
30 | @end
31 |
--------------------------------------------------------------------------------
/OKObserver/Classes/NSObject+ObservingKeypath.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSObject+ObservingKeypath.m
3 | // Pods
4 | //
5 | // Created by Draveness on 5/18/16.
6 | //
7 | //
8 |
9 | #import "NSObject+ObservingKeypath.h"
10 |
11 | @import ObjectiveC.runtime;
12 | @import ObjectiveC.message;
13 |
14 |
15 | @implementation NSObject (ObservingKeypath)
16 |
17 | - (NSMutableArray *)observingKeypath {
18 | NSMutableArray *result = objc_getAssociatedObject(self, @selector(observingKeypath));
19 | if (!result) {
20 | result = [[NSMutableArray alloc] init];
21 | [self setObservingKeypath:result];
22 | }
23 | return result;
24 | }
25 |
26 | - (void)setObservingKeypath:(NSMutableArray *)observingKeypath {
27 | objc_setAssociatedObject(self, @selector(observingKeypath), observingKeypath, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
28 | }
29 |
30 | @end
31 |
32 |
--------------------------------------------------------------------------------
/fastlane/actions/sync_build_number_to_git.rb:
--------------------------------------------------------------------------------
1 | module Fastlane
2 | module Actions
3 | module SharedValues
4 | BUILD_NUMBER = :BUILD_NUMBER
5 | end
6 | class SyncBuildNumberToGitAction < Action
7 | def self.is_git?
8 | Actions.sh 'git rev-parse HEAD'
9 | return true
10 | rescue
11 | return false
12 | end
13 |
14 | def self.run(params)
15 | if is_git?
16 | command = 'git rev-list HEAD --count'
17 | else
18 | raise "Not in a git repository."
19 | end
20 | build_number = (Actions.sh command).strip
21 | Fastlane::Actions::IncrementBuildNumberAction.run(build_number: build_number)
22 | Actions.lane_context[SharedValues::BUILD_NUMBER] = build_number
23 | end
24 |
25 | def self.output
26 | [
27 | ['BUILD_NUMBER', 'The new build number']
28 | ]
29 | end
30 | end
31 | end
32 | end
33 |
34 |
--------------------------------------------------------------------------------
/fastlane/actions/git_commit_all.rb:
--------------------------------------------------------------------------------
1 | module Fastlane
2 | module Actions
3 | class GitCommitAllAction < Action
4 | def self.run(params)
5 | Actions.sh "git commit -am \"#{params[:message]}\""
6 | end
7 |
8 | #####################################################
9 | # @!group Documentation
10 | #####################################################
11 |
12 | def self.description
13 | "Commit all unsaved changes to git."
14 | end
15 |
16 | def self.available_options
17 | [
18 | FastlaneCore::ConfigItem.new(key: :message,
19 | env_name: "FL_GIT_COMMIT_ALL",
20 | description: "The git message for the commit",
21 | is_string: true)
22 | ]
23 | end
24 |
25 | def self.is_supported?(platform)
26 | true
27 | end
28 | end
29 | end
30 | end
31 |
32 |
--------------------------------------------------------------------------------
/OKObserver.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |s|
2 | s.name = "OKObserver"
3 | s.version = "0.1.0"
4 | s.summary = "A lightweight framework which makes KVO easily to use."
5 |
6 | s.description = <<-DESC
7 | KVO is very troublesome to use, you need to call addObserver: method, override method
8 | to observe the event. All I need is when there is somthing changed, execute blocks.
9 | At first ReactiveCocoa fits my requirement, and I really had a happy time with it. But
10 | it is a swift framework and doesn't officially support cocoapods as installation method.
11 | OKObserver is created under this circumstance to help us bind model and view.
12 | DESC
13 |
14 | s.homepage = "https://github.com/draveness/OKObserver"
15 | s.license = 'MIT'
16 | s.author = { "Draveness" => "stark.draven@gmail.com" }
17 | s.source = { :git => "https://github.com/draveness/OKObserver.git", :tag => s.version.to_s }
18 |
19 | s.ios.deployment_target = '8.0'
20 |
21 | s.source_files = 'OKObserver/Classes/**/*'
22 |
23 | end
24 |
--------------------------------------------------------------------------------
/Example/OKObserver/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "40x40",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "60x60",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "ipad",
20 | "size" : "29x29",
21 | "scale" : "1x"
22 | },
23 | {
24 | "idiom" : "ipad",
25 | "size" : "29x29",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "ipad",
30 | "size" : "40x40",
31 | "scale" : "1x"
32 | },
33 | {
34 | "idiom" : "ipad",
35 | "size" : "40x40",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "ipad",
40 | "size" : "76x76",
41 | "scale" : "1x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "76x76",
46 | "scale" : "2x"
47 | }
48 | ],
49 | "info" : {
50 | "version" : 1,
51 | "author" : "xcode"
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2016 Draveness
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/Example/OKObserver/Images.xcassets/LaunchImage.launchimage/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "orientation" : "portrait",
5 | "idiom" : "iphone",
6 | "extent" : "full-screen",
7 | "minimum-system-version" : "7.0",
8 | "scale" : "2x"
9 | },
10 | {
11 | "orientation" : "portrait",
12 | "idiom" : "iphone",
13 | "subtype" : "retina4",
14 | "extent" : "full-screen",
15 | "minimum-system-version" : "7.0",
16 | "scale" : "2x"
17 | },
18 | {
19 | "orientation" : "portrait",
20 | "idiom" : "ipad",
21 | "extent" : "full-screen",
22 | "minimum-system-version" : "7.0",
23 | "scale" : "1x"
24 | },
25 | {
26 | "orientation" : "landscape",
27 | "idiom" : "ipad",
28 | "extent" : "full-screen",
29 | "minimum-system-version" : "7.0",
30 | "scale" : "1x"
31 | },
32 | {
33 | "orientation" : "portrait",
34 | "idiom" : "ipad",
35 | "extent" : "full-screen",
36 | "minimum-system-version" : "7.0",
37 | "scale" : "2x"
38 | },
39 | {
40 | "orientation" : "landscape",
41 | "idiom" : "ipad",
42 | "extent" : "full-screen",
43 | "minimum-system-version" : "7.0",
44 | "scale" : "2x"
45 | }
46 | ],
47 | "info" : {
48 | "version" : 1,
49 | "author" : "xcode"
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # OKObserver
2 |
3 | A lightweight framework which makes KVO easily to use.
4 |
5 | [](https://travis-ci.org/Draveness/OKObserver)
6 | [](http://cocoapods.org/pods/OKObserver)
7 | [](http://cocoapods.org/pods/OKObserver)
8 | [](http://cocoapods.org/pods/OKObserver)
9 |
10 | ## Installation
11 |
12 | OKObserver is available through [CocoaPods](http://cocoapods.org). To install
13 | it, simply add the following line to your Podfile:
14 |
15 | ```ruby
16 | pod "OKObserver"
17 | ```
18 |
19 | ## Usage
20 |
21 | Use `OKObserver` to bind view and model.
22 |
23 | ```objectivec
24 | [OKObserve(object, color) update:OKObserve(self.view, backgroundColor)];
25 | ```
26 |
27 | Easily to use API for KVO
28 |
29 | ```objectivec
30 | [OKObserve(object, color) whenUpdated:^(UIColor *backgroundColor) {
31 | self.view.backgroundColor = backgroundColor;
32 | }];
33 | ```
34 |
35 | The two usage above has the same function.
36 |
37 | ## Author
38 |
39 | Draveness, stark.draven@gmail.com
40 |
41 | ## License
42 |
43 | OKObserver is available under the MIT license. See the LICENSE file for more info.
44 |
--------------------------------------------------------------------------------
/Example/OKObserver/OKObserver-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | ${PRODUCT_NAME}
9 | CFBundleExecutable
10 | ${EXECUTABLE_NAME}
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | ${PRODUCT_NAME}
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | 1.0
25 | LSRequiresIPhoneOS
26 |
27 | UIMainStoryboardFile
28 | Main
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 | UISupportedInterfaceOrientations~ipad
40 |
41 | UIInterfaceOrientationPortrait
42 | UIInterfaceOrientationPortraitUpsideDown
43 | UIInterfaceOrientationLandscapeLeft
44 | UIInterfaceOrientationLandscapeRight
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/Example/OKObserver/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/Example/OKObserver/OKAppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // OKAppDelegate.m
3 | // OKObserver
4 | //
5 | // Created by Draveness on 05/18/2016.
6 | // Copyright (c) 2016 Draveness. All rights reserved.
7 | //
8 |
9 | #import "OKAppDelegate.h"
10 |
11 | @implementation OKAppDelegate
12 |
13 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
14 | {
15 | // Override point for customization after application launch.
16 | return YES;
17 | }
18 |
19 | - (void)applicationWillResignActive:(UIApplication *)application
20 | {
21 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
22 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
23 | }
24 |
25 | - (void)applicationDidEnterBackground:(UIApplication *)application
26 | {
27 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
28 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
29 | }
30 |
31 | - (void)applicationWillEnterForeground:(UIApplication *)application
32 | {
33 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
34 | }
35 |
36 | - (void)applicationDidBecomeActive:(UIApplication *)application
37 | {
38 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
39 | }
40 |
41 | - (void)applicationWillTerminate:(UIApplication *)application
42 | {
43 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
44 | }
45 |
46 | @end
47 |
--------------------------------------------------------------------------------
/OKObserver/Classes/EXTKeyPathCoding.h:
--------------------------------------------------------------------------------
1 | //
2 | // EXTKeyPathCoding.h
3 | // extobjc
4 | //
5 | // Created by Justin Spahr-Summers on 19.06.12.
6 | // Copyright (C) 2012 Justin Spahr-Summers.
7 | // Released under the MIT license.
8 | //
9 |
10 | #import
11 | #import "metamacros.h"
12 |
13 | /**
14 | * \@keypath allows compile-time verification of key paths. Given a real object
15 | * receiver and key path:
16 | *
17 | * @code
18 |
19 | NSString *UTF8StringPath = @keypath(str.lowercaseString.UTF8String);
20 | // => @"lowercaseString.UTF8String"
21 |
22 | NSString *versionPath = @keypath(NSObject, version);
23 | // => @"version"
24 |
25 | NSString *lowercaseStringPath = @keypath(NSString.new, lowercaseString);
26 | // => @"lowercaseString"
27 |
28 | * @endcode
29 | *
30 | * ... the macro returns an \c NSString containing all but the first path
31 | * component or argument (e.g., @"lowercaseString.UTF8String", @"version").
32 | *
33 | * In addition to simply creating a key path, this macro ensures that the key
34 | * path is valid at compile-time (causing a syntax error if not), and supports
35 | * refactoring, such that changing the name of the property will also update any
36 | * uses of \@keypath.
37 | */
38 | #define keypath(...) \
39 | _Pragma("clang diagnostic push") \
40 | _Pragma("clang diagnostic ignored \"-Warc-repeated-use-of-weak\"") \
41 | metamacro_if_eq(1, metamacro_argcount(__VA_ARGS__))(keypath1(__VA_ARGS__))(keypath2(__VA_ARGS__)) \
42 | _Pragma("clang diagnostic pop") \
43 |
44 | #define keypath1(PATH) \
45 | (((void)(NO && ((void)PATH, NO)), strchr(# PATH, '.') + 1))
46 |
47 | #define keypath2(OBJ, PATH) \
48 | (((void)(NO && ((void)OBJ.PATH, NO)), # PATH))
49 |
50 | /**
51 | * \@collectionKeypath allows compile-time verification of key paths across collections NSArray/NSSet etc. Given a real object
52 | * receiver, collection object receiver and related keypaths:
53 | *
54 | * @code
55 |
56 | NSString *employeesFirstNamePath = @collectionKeypath(department.employees, Employee.new, firstName)
57 | // => @"employees.firstName"
58 |
59 | NSString *employeesFirstNamePath = @collectionKeypath(Department.new, employees, Employee.new, firstName)
60 | // => @"employees.firstName"
61 |
62 | * @endcode
63 | *
64 | */
65 | #define collectionKeypath(...) \
66 | metamacro_if_eq(3, metamacro_argcount(__VA_ARGS__))(collectionKeypath3(__VA_ARGS__))(collectionKeypath4(__VA_ARGS__))
67 |
68 | #define collectionKeypath3(PATH, COLLECTION_OBJECT, COLLECTION_PATH) ([[NSString stringWithFormat:@"%s.%s",keypath(PATH), keypath(COLLECTION_OBJECT, COLLECTION_PATH)] UTF8String])
69 |
70 | #define collectionKeypath4(OBJ, PATH, COLLECTION_OBJECT, COLLECTION_PATH) ([[NSString stringWithFormat:@"%s.%s",keypath(OBJ, PATH), keypath(COLLECTION_OBJECT, COLLECTION_PATH)] UTF8String])
71 |
72 |
--------------------------------------------------------------------------------
/Example/OKObserver.xcodeproj/xcshareddata/xcschemes/OKObserver-Example.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
33 |
39 |
40 |
41 |
42 |
43 |
49 |
50 |
51 |
52 |
53 |
54 |
64 |
66 |
72 |
73 |
74 |
75 |
76 |
77 |
83 |
85 |
91 |
92 |
93 |
94 |
96 |
97 |
100 |
101 |
102 |
--------------------------------------------------------------------------------
/OKObserver/Classes/OKObserver.m:
--------------------------------------------------------------------------------
1 | //
2 | // OKObserver.m
3 | // Pods
4 | //
5 | // Created by Draveness on 5/18/16.
6 | //
7 | //
8 |
9 | #import "OKObserver.h"
10 | #import "NSObject+ObservingKeypath.h"
11 |
12 | @import ObjectiveC.runtime;
13 | @import ObjectiveC.message;
14 |
15 | @interface OKObserver ()
16 |
17 | @property (nonatomic, weak) id observee;
18 | @property (nonatomic, strong) NSString *keypath;
19 |
20 | @property (nonatomic, copy) void(^updateBlock)(id newValue);
21 |
22 | @end
23 |
24 | @implementation OKObserver
25 |
26 |
27 | static NSMutableArray *SwizzledDeallocClasses;
28 |
29 | + (void)load {
30 | SwizzledDeallocClasses = [[NSMutableArray alloc] init];
31 | }
32 |
33 | + (OKObserver *)observerWithObservee:(id)observee keypath:(NSString *)keypath {
34 | OKObserver *observer = [[OKObserver alloc] initWithObservee:observee keypath:keypath];
35 |
36 | return observer;
37 | }
38 |
39 | - (instancetype)initWithObservee:(id)observee keypath:(NSString *)keypath {
40 | if (self = [super init]) {
41 | _observee = observee;
42 | _keypath = keypath;
43 |
44 |
45 | }
46 | return self;
47 | }
48 |
49 | - (void)whenUpdated:(void (^)(id))updateBlock {
50 | [_observee addObserver:self
51 | forKeyPath:_keypath
52 | options:NSKeyValueObservingOptionNew
53 | context:NULL];
54 | [[_observee observingKeypath] addObject:_keypath];
55 | [self swizzledDeallocSelectorForObject:_observee];
56 |
57 | _updateBlock = updateBlock;
58 | id newValue = [self.observee valueForKeyPath:self.keypath];
59 | _updateBlock(newValue);
60 | }
61 |
62 | - (void)update:(OKObserver *)observer {
63 | [self whenUpdated:_updateBlock = ^(id newValue) {
64 | [observer.observee setValue:newValue forKeyPath:observer.keypath];
65 | }];
66 | }
67 |
68 | - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
69 | if ([keyPath isEqualToString:self.keypath]) {
70 | id newValue = change[NSKeyValueChangeNewKey];
71 | _updateBlock(newValue);
72 | }
73 | }
74 |
75 | #pragma mark - Swizzling
76 |
77 | - (void)swizzledDeallocSelectorForObject:(id)observee {
78 | Class classToSwizzle = [_observee class];
79 |
80 | @synchronized (SwizzledDeallocClasses) {
81 | NSString *className = NSStringFromClass(classToSwizzle);
82 | if (![SwizzledDeallocClasses containsObject:className]) {
83 | SEL deallocSelector = sel_registerName("dealloc");
84 |
85 | __block void (*originalDealloc)(__unsafe_unretained id, SEL) = NULL;
86 |
87 | id newDealloc = ^(__unsafe_unretained id objSelf) {
88 | for (NSString *keypath in [observee observingKeypath]) {
89 | [observee removeObserver:self forKeyPath:keypath];
90 | }
91 | [observee setObservingKeypath:nil];
92 |
93 | if (originalDealloc == NULL) {
94 | struct objc_super superInfo = {
95 | .receiver = objSelf,
96 | .super_class = class_getSuperclass(classToSwizzle)
97 | };
98 |
99 | void (*msgSend)(struct objc_super *, SEL) = (__typeof__(msgSend))objc_msgSendSuper;
100 | msgSend(&superInfo, deallocSelector);
101 | } else {
102 | originalDealloc(objSelf, deallocSelector);
103 | }
104 | };
105 |
106 | IMP newDeallocIMP = imp_implementationWithBlock(newDealloc);
107 |
108 | if (!class_addMethod(classToSwizzle, deallocSelector, newDeallocIMP, "v@:")) {
109 | // The class already contains a method implementation.
110 | Method deallocMethod = class_getInstanceMethod(classToSwizzle, deallocSelector);
111 |
112 | // We need to store original implementation before setting new implementation
113 | // in case method is called at the time of setting.
114 | originalDealloc = (void(*)(__unsafe_unretained id, SEL))method_getImplementation(deallocMethod);
115 |
116 | // We need to store original implementation again, in case it just changed.
117 | originalDealloc = (void(*)(__unsafe_unretained id, SEL))method_setImplementation(deallocMethod, newDeallocIMP);
118 | }
119 |
120 | [SwizzledDeallocClasses addObject:className];
121 | }
122 | }
123 | }
124 |
125 | @end
126 |
--------------------------------------------------------------------------------
/Example/OKObserver.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 6003F58E195388D20070C39A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F58D195388D20070C39A /* Foundation.framework */; };
11 | 6003F590195388D20070C39A /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F58F195388D20070C39A /* CoreGraphics.framework */; };
12 | 6003F592195388D20070C39A /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F591195388D20070C39A /* UIKit.framework */; };
13 | 6003F598195388D20070C39A /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 6003F596195388D20070C39A /* InfoPlist.strings */; };
14 | 6003F59A195388D20070C39A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6003F599195388D20070C39A /* main.m */; };
15 | 6003F59E195388D20070C39A /* OKAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6003F59D195388D20070C39A /* OKAppDelegate.m */; };
16 | 6003F5A7195388D20070C39A /* OKViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6003F5A6195388D20070C39A /* OKViewController.m */; };
17 | 6003F5A9195388D20070C39A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6003F5A8195388D20070C39A /* Images.xcassets */; };
18 | 6003F5B0195388D20070C39A /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F5AF195388D20070C39A /* XCTest.framework */; };
19 | 6003F5B1195388D20070C39A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F58D195388D20070C39A /* Foundation.framework */; };
20 | 6003F5B2195388D20070C39A /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F591195388D20070C39A /* UIKit.framework */; };
21 | 6003F5BA195388D20070C39A /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 6003F5B8195388D20070C39A /* InfoPlist.strings */; };
22 | 6003F5BC195388D20070C39A /* Tests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6003F5BB195388D20070C39A /* Tests.m */; };
23 | 728E05331CECB0C70043EE32 /* XXObject.m in Sources */ = {isa = PBXBuildFile; fileRef = 728E05321CECB0C70043EE32 /* XXObject.m */; };
24 | 873B8AEB1B1F5CCA007FD442 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 873B8AEA1B1F5CCA007FD442 /* Main.storyboard */; };
25 | A81C1E5CFBACC17F096DFF8D /* Pods_OKObserver_Tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B4E290A60EAC40112D147673 /* Pods_OKObserver_Tests.framework */; };
26 | C8FDF618C51C9F290D967C2E /* Pods_OKObserver_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9F82DA1E5552B0B63AAA2528 /* Pods_OKObserver_Example.framework */; };
27 | /* End PBXBuildFile section */
28 |
29 | /* Begin PBXContainerItemProxy section */
30 | 6003F5B3195388D20070C39A /* PBXContainerItemProxy */ = {
31 | isa = PBXContainerItemProxy;
32 | containerPortal = 6003F582195388D10070C39A /* Project object */;
33 | proxyType = 1;
34 | remoteGlobalIDString = 6003F589195388D20070C39A;
35 | remoteInfo = OKObserver;
36 | };
37 | /* End PBXContainerItemProxy section */
38 |
39 | /* Begin PBXFileReference section */
40 | 2F0D94B829998A6D0DD0AAAA /* Pods-OKObserver_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OKObserver_Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-OKObserver_Tests/Pods-OKObserver_Tests.debug.xcconfig"; sourceTree = ""; };
41 | 3A0448665801C104A9EA6720 /* Pods-OKObserver_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OKObserver_Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-OKObserver_Tests/Pods-OKObserver_Tests.release.xcconfig"; sourceTree = ""; };
42 | 5052914208A19F9BDC23C4B0 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = ""; };
43 | 6003F58A195388D20070C39A /* OKObserver_Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = OKObserver_Example.app; sourceTree = BUILT_PRODUCTS_DIR; };
44 | 6003F58D195388D20070C39A /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
45 | 6003F58F195388D20070C39A /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
46 | 6003F591195388D20070C39A /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
47 | 6003F595195388D20070C39A /* OKObserver-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "OKObserver-Info.plist"; sourceTree = ""; };
48 | 6003F597195388D20070C39A /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; };
49 | 6003F599195388D20070C39A /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
50 | 6003F59B195388D20070C39A /* OKObserver-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "OKObserver-Prefix.pch"; sourceTree = ""; };
51 | 6003F59C195388D20070C39A /* OKAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OKAppDelegate.h; sourceTree = ""; };
52 | 6003F59D195388D20070C39A /* OKAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OKAppDelegate.m; sourceTree = ""; };
53 | 6003F5A5195388D20070C39A /* OKViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = OKViewController.h; sourceTree = ""; };
54 | 6003F5A6195388D20070C39A /* OKViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OKViewController.m; sourceTree = ""; };
55 | 6003F5A8195388D20070C39A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; };
56 | 6003F5AE195388D20070C39A /* OKObserver_Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = OKObserver_Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
57 | 6003F5AF195388D20070C39A /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; };
58 | 6003F5B7195388D20070C39A /* Tests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Tests-Info.plist"; sourceTree = ""; };
59 | 6003F5B9195388D20070C39A /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; };
60 | 6003F5BB195388D20070C39A /* Tests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Tests.m; sourceTree = ""; };
61 | 606FC2411953D9B200FFA9A0 /* Tests-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Tests-Prefix.pch"; sourceTree = ""; };
62 | 728E05311CECB0C70043EE32 /* XXObject.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = XXObject.h; sourceTree = ""; };
63 | 728E05321CECB0C70043EE32 /* XXObject.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = XXObject.m; sourceTree = ""; };
64 | 873B8AEA1B1F5CCA007FD442 /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = ""; };
65 | 87EF675D222DCD0F9CB90FCD /* Pods-OKObserver_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OKObserver_Example.release.xcconfig"; path = "Pods/Target Support Files/Pods-OKObserver_Example/Pods-OKObserver_Example.release.xcconfig"; sourceTree = ""; };
66 | 9141E2533DDA672CA564680D /* OKObserver.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = OKObserver.podspec; path = ../OKObserver.podspec; sourceTree = ""; };
67 | 9144D3D6B9448411B7751F2F /* Pods-OKObserver_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OKObserver_Example.debug.xcconfig"; path = "Pods/Target Support Files/Pods-OKObserver_Example/Pods-OKObserver_Example.debug.xcconfig"; sourceTree = ""; };
68 | 9F82DA1E5552B0B63AAA2528 /* Pods_OKObserver_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_OKObserver_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; };
69 | B4E290A60EAC40112D147673 /* Pods_OKObserver_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_OKObserver_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; };
70 | C605D964621B4C7464742C8D /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = ""; };
71 | /* End PBXFileReference section */
72 |
73 | /* Begin PBXFrameworksBuildPhase section */
74 | 6003F587195388D20070C39A /* Frameworks */ = {
75 | isa = PBXFrameworksBuildPhase;
76 | buildActionMask = 2147483647;
77 | files = (
78 | 6003F590195388D20070C39A /* CoreGraphics.framework in Frameworks */,
79 | 6003F592195388D20070C39A /* UIKit.framework in Frameworks */,
80 | 6003F58E195388D20070C39A /* Foundation.framework in Frameworks */,
81 | C8FDF618C51C9F290D967C2E /* Pods_OKObserver_Example.framework in Frameworks */,
82 | );
83 | runOnlyForDeploymentPostprocessing = 0;
84 | };
85 | 6003F5AB195388D20070C39A /* Frameworks */ = {
86 | isa = PBXFrameworksBuildPhase;
87 | buildActionMask = 2147483647;
88 | files = (
89 | 6003F5B0195388D20070C39A /* XCTest.framework in Frameworks */,
90 | 6003F5B2195388D20070C39A /* UIKit.framework in Frameworks */,
91 | 6003F5B1195388D20070C39A /* Foundation.framework in Frameworks */,
92 | A81C1E5CFBACC17F096DFF8D /* Pods_OKObserver_Tests.framework in Frameworks */,
93 | );
94 | runOnlyForDeploymentPostprocessing = 0;
95 | };
96 | /* End PBXFrameworksBuildPhase section */
97 |
98 | /* Begin PBXGroup section */
99 | 0172A996DFAD2C8CF24EC1A2 /* Pods */ = {
100 | isa = PBXGroup;
101 | children = (
102 | 9144D3D6B9448411B7751F2F /* Pods-OKObserver_Example.debug.xcconfig */,
103 | 87EF675D222DCD0F9CB90FCD /* Pods-OKObserver_Example.release.xcconfig */,
104 | 2F0D94B829998A6D0DD0AAAA /* Pods-OKObserver_Tests.debug.xcconfig */,
105 | 3A0448665801C104A9EA6720 /* Pods-OKObserver_Tests.release.xcconfig */,
106 | );
107 | name = Pods;
108 | sourceTree = "";
109 | };
110 | 6003F581195388D10070C39A = {
111 | isa = PBXGroup;
112 | children = (
113 | 60FF7A9C1954A5C5007DD14C /* Podspec Metadata */,
114 | 6003F593195388D20070C39A /* Example for OKObserver */,
115 | 6003F5B5195388D20070C39A /* Tests */,
116 | 6003F58C195388D20070C39A /* Frameworks */,
117 | 6003F58B195388D20070C39A /* Products */,
118 | 0172A996DFAD2C8CF24EC1A2 /* Pods */,
119 | );
120 | sourceTree = "";
121 | };
122 | 6003F58B195388D20070C39A /* Products */ = {
123 | isa = PBXGroup;
124 | children = (
125 | 6003F58A195388D20070C39A /* OKObserver_Example.app */,
126 | 6003F5AE195388D20070C39A /* OKObserver_Tests.xctest */,
127 | );
128 | name = Products;
129 | sourceTree = "";
130 | };
131 | 6003F58C195388D20070C39A /* Frameworks */ = {
132 | isa = PBXGroup;
133 | children = (
134 | 6003F58D195388D20070C39A /* Foundation.framework */,
135 | 6003F58F195388D20070C39A /* CoreGraphics.framework */,
136 | 6003F591195388D20070C39A /* UIKit.framework */,
137 | 6003F5AF195388D20070C39A /* XCTest.framework */,
138 | 9F82DA1E5552B0B63AAA2528 /* Pods_OKObserver_Example.framework */,
139 | B4E290A60EAC40112D147673 /* Pods_OKObserver_Tests.framework */,
140 | );
141 | name = Frameworks;
142 | sourceTree = "";
143 | };
144 | 6003F593195388D20070C39A /* Example for OKObserver */ = {
145 | isa = PBXGroup;
146 | children = (
147 | 6003F59C195388D20070C39A /* OKAppDelegate.h */,
148 | 6003F59D195388D20070C39A /* OKAppDelegate.m */,
149 | 873B8AEA1B1F5CCA007FD442 /* Main.storyboard */,
150 | 6003F5A5195388D20070C39A /* OKViewController.h */,
151 | 6003F5A6195388D20070C39A /* OKViewController.m */,
152 | 728E05311CECB0C70043EE32 /* XXObject.h */,
153 | 728E05321CECB0C70043EE32 /* XXObject.m */,
154 | 6003F5A8195388D20070C39A /* Images.xcassets */,
155 | 6003F594195388D20070C39A /* Supporting Files */,
156 | );
157 | name = "Example for OKObserver";
158 | path = OKObserver;
159 | sourceTree = "";
160 | };
161 | 6003F594195388D20070C39A /* Supporting Files */ = {
162 | isa = PBXGroup;
163 | children = (
164 | 6003F595195388D20070C39A /* OKObserver-Info.plist */,
165 | 6003F596195388D20070C39A /* InfoPlist.strings */,
166 | 6003F599195388D20070C39A /* main.m */,
167 | 6003F59B195388D20070C39A /* OKObserver-Prefix.pch */,
168 | );
169 | name = "Supporting Files";
170 | sourceTree = "";
171 | };
172 | 6003F5B5195388D20070C39A /* Tests */ = {
173 | isa = PBXGroup;
174 | children = (
175 | 6003F5BB195388D20070C39A /* Tests.m */,
176 | 6003F5B6195388D20070C39A /* Supporting Files */,
177 | );
178 | path = Tests;
179 | sourceTree = "";
180 | };
181 | 6003F5B6195388D20070C39A /* Supporting Files */ = {
182 | isa = PBXGroup;
183 | children = (
184 | 6003F5B7195388D20070C39A /* Tests-Info.plist */,
185 | 6003F5B8195388D20070C39A /* InfoPlist.strings */,
186 | 606FC2411953D9B200FFA9A0 /* Tests-Prefix.pch */,
187 | );
188 | name = "Supporting Files";
189 | sourceTree = "";
190 | };
191 | 60FF7A9C1954A5C5007DD14C /* Podspec Metadata */ = {
192 | isa = PBXGroup;
193 | children = (
194 | 9141E2533DDA672CA564680D /* OKObserver.podspec */,
195 | 5052914208A19F9BDC23C4B0 /* README.md */,
196 | C605D964621B4C7464742C8D /* LICENSE */,
197 | );
198 | name = "Podspec Metadata";
199 | sourceTree = "";
200 | };
201 | /* End PBXGroup section */
202 |
203 | /* Begin PBXNativeTarget section */
204 | 6003F589195388D20070C39A /* OKObserver_Example */ = {
205 | isa = PBXNativeTarget;
206 | buildConfigurationList = 6003F5BF195388D20070C39A /* Build configuration list for PBXNativeTarget "OKObserver_Example" */;
207 | buildPhases = (
208 | EA867EEE6668783E85C3AA92 /* 📦 Check Pods Manifest.lock */,
209 | 6003F586195388D20070C39A /* Sources */,
210 | 6003F587195388D20070C39A /* Frameworks */,
211 | 6003F588195388D20070C39A /* Resources */,
212 | E5809A73AFFD5DC9C8CC982F /* 📦 Embed Pods Frameworks */,
213 | D4CB71AF72288900DD53DC58 /* 📦 Copy Pods Resources */,
214 | );
215 | buildRules = (
216 | );
217 | dependencies = (
218 | );
219 | name = OKObserver_Example;
220 | productName = OKObserver;
221 | productReference = 6003F58A195388D20070C39A /* OKObserver_Example.app */;
222 | productType = "com.apple.product-type.application";
223 | };
224 | 6003F5AD195388D20070C39A /* OKObserver_Tests */ = {
225 | isa = PBXNativeTarget;
226 | buildConfigurationList = 6003F5C2195388D20070C39A /* Build configuration list for PBXNativeTarget "OKObserver_Tests" */;
227 | buildPhases = (
228 | D45D64C6D394258712301EB8 /* 📦 Check Pods Manifest.lock */,
229 | 6003F5AA195388D20070C39A /* Sources */,
230 | 6003F5AB195388D20070C39A /* Frameworks */,
231 | 6003F5AC195388D20070C39A /* Resources */,
232 | 8DE1F124571246FA8BA9D762 /* 📦 Embed Pods Frameworks */,
233 | A749340159E4B39BE4484653 /* 📦 Copy Pods Resources */,
234 | );
235 | buildRules = (
236 | );
237 | dependencies = (
238 | 6003F5B4195388D20070C39A /* PBXTargetDependency */,
239 | );
240 | name = OKObserver_Tests;
241 | productName = OKObserverTests;
242 | productReference = 6003F5AE195388D20070C39A /* OKObserver_Tests.xctest */;
243 | productType = "com.apple.product-type.bundle.unit-test";
244 | };
245 | /* End PBXNativeTarget section */
246 |
247 | /* Begin PBXProject section */
248 | 6003F582195388D10070C39A /* Project object */ = {
249 | isa = PBXProject;
250 | attributes = {
251 | CLASSPREFIX = OK;
252 | LastUpgradeCheck = 0720;
253 | ORGANIZATIONNAME = Draveness;
254 | TargetAttributes = {
255 | 6003F5AD195388D20070C39A = {
256 | TestTargetID = 6003F589195388D20070C39A;
257 | };
258 | };
259 | };
260 | buildConfigurationList = 6003F585195388D10070C39A /* Build configuration list for PBXProject "OKObserver" */;
261 | compatibilityVersion = "Xcode 3.2";
262 | developmentRegion = English;
263 | hasScannedForEncodings = 0;
264 | knownRegions = (
265 | en,
266 | Base,
267 | );
268 | mainGroup = 6003F581195388D10070C39A;
269 | productRefGroup = 6003F58B195388D20070C39A /* Products */;
270 | projectDirPath = "";
271 | projectRoot = "";
272 | targets = (
273 | 6003F589195388D20070C39A /* OKObserver_Example */,
274 | 6003F5AD195388D20070C39A /* OKObserver_Tests */,
275 | );
276 | };
277 | /* End PBXProject section */
278 |
279 | /* Begin PBXResourcesBuildPhase section */
280 | 6003F588195388D20070C39A /* Resources */ = {
281 | isa = PBXResourcesBuildPhase;
282 | buildActionMask = 2147483647;
283 | files = (
284 | 873B8AEB1B1F5CCA007FD442 /* Main.storyboard in Resources */,
285 | 6003F5A9195388D20070C39A /* Images.xcassets in Resources */,
286 | 6003F598195388D20070C39A /* InfoPlist.strings in Resources */,
287 | );
288 | runOnlyForDeploymentPostprocessing = 0;
289 | };
290 | 6003F5AC195388D20070C39A /* Resources */ = {
291 | isa = PBXResourcesBuildPhase;
292 | buildActionMask = 2147483647;
293 | files = (
294 | 6003F5BA195388D20070C39A /* InfoPlist.strings in Resources */,
295 | );
296 | runOnlyForDeploymentPostprocessing = 0;
297 | };
298 | /* End PBXResourcesBuildPhase section */
299 |
300 | /* Begin PBXShellScriptBuildPhase section */
301 | 8DE1F124571246FA8BA9D762 /* 📦 Embed Pods Frameworks */ = {
302 | isa = PBXShellScriptBuildPhase;
303 | buildActionMask = 2147483647;
304 | files = (
305 | );
306 | inputPaths = (
307 | );
308 | name = "📦 Embed Pods Frameworks";
309 | outputPaths = (
310 | );
311 | runOnlyForDeploymentPostprocessing = 0;
312 | shellPath = /bin/sh;
313 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-OKObserver_Tests/Pods-OKObserver_Tests-frameworks.sh\"\n";
314 | showEnvVarsInLog = 0;
315 | };
316 | A749340159E4B39BE4484653 /* 📦 Copy Pods Resources */ = {
317 | isa = PBXShellScriptBuildPhase;
318 | buildActionMask = 2147483647;
319 | files = (
320 | );
321 | inputPaths = (
322 | );
323 | name = "📦 Copy Pods Resources";
324 | outputPaths = (
325 | );
326 | runOnlyForDeploymentPostprocessing = 0;
327 | shellPath = /bin/sh;
328 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-OKObserver_Tests/Pods-OKObserver_Tests-resources.sh\"\n";
329 | showEnvVarsInLog = 0;
330 | };
331 | D45D64C6D394258712301EB8 /* 📦 Check Pods Manifest.lock */ = {
332 | isa = PBXShellScriptBuildPhase;
333 | buildActionMask = 2147483647;
334 | files = (
335 | );
336 | inputPaths = (
337 | );
338 | name = "📦 Check Pods Manifest.lock";
339 | outputPaths = (
340 | );
341 | runOnlyForDeploymentPostprocessing = 0;
342 | shellPath = /bin/sh;
343 | shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n";
344 | showEnvVarsInLog = 0;
345 | };
346 | D4CB71AF72288900DD53DC58 /* 📦 Copy Pods Resources */ = {
347 | isa = PBXShellScriptBuildPhase;
348 | buildActionMask = 2147483647;
349 | files = (
350 | );
351 | inputPaths = (
352 | );
353 | name = "📦 Copy Pods Resources";
354 | outputPaths = (
355 | );
356 | runOnlyForDeploymentPostprocessing = 0;
357 | shellPath = /bin/sh;
358 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-OKObserver_Example/Pods-OKObserver_Example-resources.sh\"\n";
359 | showEnvVarsInLog = 0;
360 | };
361 | E5809A73AFFD5DC9C8CC982F /* 📦 Embed Pods Frameworks */ = {
362 | isa = PBXShellScriptBuildPhase;
363 | buildActionMask = 2147483647;
364 | files = (
365 | );
366 | inputPaths = (
367 | );
368 | name = "📦 Embed Pods Frameworks";
369 | outputPaths = (
370 | );
371 | runOnlyForDeploymentPostprocessing = 0;
372 | shellPath = /bin/sh;
373 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-OKObserver_Example/Pods-OKObserver_Example-frameworks.sh\"\n";
374 | showEnvVarsInLog = 0;
375 | };
376 | EA867EEE6668783E85C3AA92 /* 📦 Check Pods Manifest.lock */ = {
377 | isa = PBXShellScriptBuildPhase;
378 | buildActionMask = 2147483647;
379 | files = (
380 | );
381 | inputPaths = (
382 | );
383 | name = "📦 Check Pods Manifest.lock";
384 | outputPaths = (
385 | );
386 | runOnlyForDeploymentPostprocessing = 0;
387 | shellPath = /bin/sh;
388 | shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n";
389 | showEnvVarsInLog = 0;
390 | };
391 | /* End PBXShellScriptBuildPhase section */
392 |
393 | /* Begin PBXSourcesBuildPhase section */
394 | 6003F586195388D20070C39A /* Sources */ = {
395 | isa = PBXSourcesBuildPhase;
396 | buildActionMask = 2147483647;
397 | files = (
398 | 728E05331CECB0C70043EE32 /* XXObject.m in Sources */,
399 | 6003F59E195388D20070C39A /* OKAppDelegate.m in Sources */,
400 | 6003F5A7195388D20070C39A /* OKViewController.m in Sources */,
401 | 6003F59A195388D20070C39A /* main.m in Sources */,
402 | );
403 | runOnlyForDeploymentPostprocessing = 0;
404 | };
405 | 6003F5AA195388D20070C39A /* Sources */ = {
406 | isa = PBXSourcesBuildPhase;
407 | buildActionMask = 2147483647;
408 | files = (
409 | 6003F5BC195388D20070C39A /* Tests.m in Sources */,
410 | );
411 | runOnlyForDeploymentPostprocessing = 0;
412 | };
413 | /* End PBXSourcesBuildPhase section */
414 |
415 | /* Begin PBXTargetDependency section */
416 | 6003F5B4195388D20070C39A /* PBXTargetDependency */ = {
417 | isa = PBXTargetDependency;
418 | target = 6003F589195388D20070C39A /* OKObserver_Example */;
419 | targetProxy = 6003F5B3195388D20070C39A /* PBXContainerItemProxy */;
420 | };
421 | /* End PBXTargetDependency section */
422 |
423 | /* Begin PBXVariantGroup section */
424 | 6003F596195388D20070C39A /* InfoPlist.strings */ = {
425 | isa = PBXVariantGroup;
426 | children = (
427 | 6003F597195388D20070C39A /* en */,
428 | );
429 | name = InfoPlist.strings;
430 | sourceTree = "";
431 | };
432 | 6003F5B8195388D20070C39A /* InfoPlist.strings */ = {
433 | isa = PBXVariantGroup;
434 | children = (
435 | 6003F5B9195388D20070C39A /* en */,
436 | );
437 | name = InfoPlist.strings;
438 | sourceTree = "";
439 | };
440 | /* End PBXVariantGroup section */
441 |
442 | /* Begin XCBuildConfiguration section */
443 | 6003F5BD195388D20070C39A /* Debug */ = {
444 | isa = XCBuildConfiguration;
445 | buildSettings = {
446 | ALWAYS_SEARCH_USER_PATHS = NO;
447 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
448 | CLANG_CXX_LIBRARY = "libc++";
449 | CLANG_ENABLE_MODULES = YES;
450 | CLANG_ENABLE_OBJC_ARC = YES;
451 | CLANG_WARN_BOOL_CONVERSION = YES;
452 | CLANG_WARN_CONSTANT_CONVERSION = YES;
453 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
454 | CLANG_WARN_EMPTY_BODY = YES;
455 | CLANG_WARN_ENUM_CONVERSION = YES;
456 | CLANG_WARN_INT_CONVERSION = YES;
457 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
458 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
459 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
460 | COPY_PHASE_STRIP = NO;
461 | ENABLE_TESTABILITY = YES;
462 | GCC_C_LANGUAGE_STANDARD = gnu99;
463 | GCC_DYNAMIC_NO_PIC = NO;
464 | GCC_OPTIMIZATION_LEVEL = 0;
465 | GCC_PREPROCESSOR_DEFINITIONS = (
466 | "DEBUG=1",
467 | "$(inherited)",
468 | );
469 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
470 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
471 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
472 | GCC_WARN_UNDECLARED_SELECTOR = YES;
473 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
474 | GCC_WARN_UNUSED_FUNCTION = YES;
475 | GCC_WARN_UNUSED_VARIABLE = YES;
476 | IPHONEOS_DEPLOYMENT_TARGET = 8.3;
477 | ONLY_ACTIVE_ARCH = YES;
478 | SDKROOT = iphoneos;
479 | TARGETED_DEVICE_FAMILY = "1,2";
480 | };
481 | name = Debug;
482 | };
483 | 6003F5BE195388D20070C39A /* Release */ = {
484 | isa = XCBuildConfiguration;
485 | buildSettings = {
486 | ALWAYS_SEARCH_USER_PATHS = NO;
487 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
488 | CLANG_CXX_LIBRARY = "libc++";
489 | CLANG_ENABLE_MODULES = YES;
490 | CLANG_ENABLE_OBJC_ARC = YES;
491 | CLANG_WARN_BOOL_CONVERSION = YES;
492 | CLANG_WARN_CONSTANT_CONVERSION = YES;
493 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
494 | CLANG_WARN_EMPTY_BODY = YES;
495 | CLANG_WARN_ENUM_CONVERSION = YES;
496 | CLANG_WARN_INT_CONVERSION = YES;
497 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
498 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
499 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
500 | COPY_PHASE_STRIP = YES;
501 | ENABLE_NS_ASSERTIONS = NO;
502 | GCC_C_LANGUAGE_STANDARD = gnu99;
503 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
504 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
505 | GCC_WARN_UNDECLARED_SELECTOR = YES;
506 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
507 | GCC_WARN_UNUSED_FUNCTION = YES;
508 | GCC_WARN_UNUSED_VARIABLE = YES;
509 | IPHONEOS_DEPLOYMENT_TARGET = 8.3;
510 | SDKROOT = iphoneos;
511 | TARGETED_DEVICE_FAMILY = "1,2";
512 | VALIDATE_PRODUCT = YES;
513 | };
514 | name = Release;
515 | };
516 | 6003F5C0195388D20070C39A /* Debug */ = {
517 | isa = XCBuildConfiguration;
518 | baseConfigurationReference = 9144D3D6B9448411B7751F2F /* Pods-OKObserver_Example.debug.xcconfig */;
519 | buildSettings = {
520 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
521 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
522 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
523 | GCC_PREFIX_HEADER = "OKObserver/OKObserver-Prefix.pch";
524 | INFOPLIST_FILE = "OKObserver/OKObserver-Info.plist";
525 | MODULE_NAME = ExampleApp;
526 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.${PRODUCT_NAME:rfc1034identifier}";
527 | PRODUCT_NAME = "$(TARGET_NAME)";
528 | WRAPPER_EXTENSION = app;
529 | };
530 | name = Debug;
531 | };
532 | 6003F5C1195388D20070C39A /* Release */ = {
533 | isa = XCBuildConfiguration;
534 | baseConfigurationReference = 87EF675D222DCD0F9CB90FCD /* Pods-OKObserver_Example.release.xcconfig */;
535 | buildSettings = {
536 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
537 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
538 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
539 | GCC_PREFIX_HEADER = "OKObserver/OKObserver-Prefix.pch";
540 | INFOPLIST_FILE = "OKObserver/OKObserver-Info.plist";
541 | MODULE_NAME = ExampleApp;
542 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.${PRODUCT_NAME:rfc1034identifier}";
543 | PRODUCT_NAME = "$(TARGET_NAME)";
544 | WRAPPER_EXTENSION = app;
545 | };
546 | name = Release;
547 | };
548 | 6003F5C3195388D20070C39A /* Debug */ = {
549 | isa = XCBuildConfiguration;
550 | baseConfigurationReference = 2F0D94B829998A6D0DD0AAAA /* Pods-OKObserver_Tests.debug.xcconfig */;
551 | buildSettings = {
552 | BUNDLE_LOADER = "$(TEST_HOST)";
553 | FRAMEWORK_SEARCH_PATHS = (
554 | "$(SDKROOT)/Developer/Library/Frameworks",
555 | "$(inherited)",
556 | "$(DEVELOPER_FRAMEWORKS_DIR)",
557 | );
558 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
559 | GCC_PREFIX_HEADER = "Tests/Tests-Prefix.pch";
560 | GCC_PREPROCESSOR_DEFINITIONS = (
561 | "DEBUG=1",
562 | "$(inherited)",
563 | );
564 | INFOPLIST_FILE = "Tests/Tests-Info.plist";
565 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.${PRODUCT_NAME:rfc1034identifier}";
566 | PRODUCT_NAME = "$(TARGET_NAME)";
567 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/OKObserver_Example.app/OKObserver_Example";
568 | WRAPPER_EXTENSION = xctest;
569 | };
570 | name = Debug;
571 | };
572 | 6003F5C4195388D20070C39A /* Release */ = {
573 | isa = XCBuildConfiguration;
574 | baseConfigurationReference = 3A0448665801C104A9EA6720 /* Pods-OKObserver_Tests.release.xcconfig */;
575 | buildSettings = {
576 | BUNDLE_LOADER = "$(TEST_HOST)";
577 | FRAMEWORK_SEARCH_PATHS = (
578 | "$(SDKROOT)/Developer/Library/Frameworks",
579 | "$(inherited)",
580 | "$(DEVELOPER_FRAMEWORKS_DIR)",
581 | );
582 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
583 | GCC_PREFIX_HEADER = "Tests/Tests-Prefix.pch";
584 | INFOPLIST_FILE = "Tests/Tests-Info.plist";
585 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.${PRODUCT_NAME:rfc1034identifier}";
586 | PRODUCT_NAME = "$(TARGET_NAME)";
587 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/OKObserver_Example.app/OKObserver_Example";
588 | WRAPPER_EXTENSION = xctest;
589 | };
590 | name = Release;
591 | };
592 | /* End XCBuildConfiguration section */
593 |
594 | /* Begin XCConfigurationList section */
595 | 6003F585195388D10070C39A /* Build configuration list for PBXProject "OKObserver" */ = {
596 | isa = XCConfigurationList;
597 | buildConfigurations = (
598 | 6003F5BD195388D20070C39A /* Debug */,
599 | 6003F5BE195388D20070C39A /* Release */,
600 | );
601 | defaultConfigurationIsVisible = 0;
602 | defaultConfigurationName = Release;
603 | };
604 | 6003F5BF195388D20070C39A /* Build configuration list for PBXNativeTarget "OKObserver_Example" */ = {
605 | isa = XCConfigurationList;
606 | buildConfigurations = (
607 | 6003F5C0195388D20070C39A /* Debug */,
608 | 6003F5C1195388D20070C39A /* Release */,
609 | );
610 | defaultConfigurationIsVisible = 0;
611 | defaultConfigurationName = Release;
612 | };
613 | 6003F5C2195388D20070C39A /* Build configuration list for PBXNativeTarget "OKObserver_Tests" */ = {
614 | isa = XCConfigurationList;
615 | buildConfigurations = (
616 | 6003F5C3195388D20070C39A /* Debug */,
617 | 6003F5C4195388D20070C39A /* Release */,
618 | );
619 | defaultConfigurationIsVisible = 0;
620 | defaultConfigurationName = Release;
621 | };
622 | /* End XCConfigurationList section */
623 | };
624 | rootObject = 6003F582195388D10070C39A /* Project object */;
625 | }
626 |
--------------------------------------------------------------------------------
/OKObserver/Classes/metamacros.h:
--------------------------------------------------------------------------------
1 | /**
2 | * Macros for metaprogramming
3 | * ExtendedC
4 | *
5 | * Copyright (C) 2012 Justin Spahr-Summers
6 | * Released under the MIT license
7 | */
8 |
9 | #ifndef EXTC_METAMACROS_H
10 | #define EXTC_METAMACROS_H
11 |
12 |
13 | /**
14 | * Executes one or more expressions (which may have a void type, such as a call
15 | * to a function that returns no value) and always returns true.
16 | */
17 | #define metamacro_exprify(...) \
18 | ((__VA_ARGS__), true)
19 |
20 | /**
21 | * Returns a string representation of VALUE after full macro expansion.
22 | */
23 | #define metamacro_stringify(VALUE) \
24 | metamacro_stringify_(VALUE)
25 |
26 | /**
27 | * Returns A and B concatenated after full macro expansion.
28 | */
29 | #define metamacro_concat(A, B) \
30 | metamacro_concat_(A, B)
31 |
32 | /**
33 | * Returns the Nth variadic argument (starting from zero). At least
34 | * N + 1 variadic arguments must be given. N must be between zero and twenty,
35 | * inclusive.
36 | */
37 | #define metamacro_at(N, ...) \
38 | metamacro_concat(metamacro_at, N)(__VA_ARGS__)
39 |
40 | /**
41 | * Returns the number of arguments (up to twenty) provided to the macro. At
42 | * least one argument must be provided.
43 | *
44 | * Inspired by P99: http://p99.gforge.inria.fr
45 | */
46 | #define metamacro_argcount(...) \
47 | 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)
48 |
49 | /**
50 | * Identical to #metamacro_foreach_cxt, except that no CONTEXT argument is
51 | * given. Only the index and current argument will thus be passed to MACRO.
52 | */
53 | #define metamacro_foreach(MACRO, SEP, ...) \
54 | metamacro_foreach_cxt(metamacro_foreach_iter, SEP, MACRO, __VA_ARGS__)
55 |
56 | /**
57 | * For each consecutive variadic argument (up to twenty), MACRO is passed the
58 | * zero-based index of the current argument, CONTEXT, and then the argument
59 | * itself. The results of adjoining invocations of MACRO are then separated by
60 | * SEP.
61 | *
62 | * Inspired by P99: http://p99.gforge.inria.fr
63 | */
64 | #define metamacro_foreach_cxt(MACRO, SEP, CONTEXT, ...) \
65 | metamacro_concat(metamacro_foreach_cxt, metamacro_argcount(__VA_ARGS__))(MACRO, SEP, CONTEXT, __VA_ARGS__)
66 |
67 | /**
68 | * Identical to #metamacro_foreach_cxt. This can be used when the former would
69 | * fail due to recursive macro expansion.
70 | */
71 | #define metamacro_foreach_cxt_recursive(MACRO, SEP, CONTEXT, ...) \
72 | metamacro_concat(metamacro_foreach_cxt_recursive, metamacro_argcount(__VA_ARGS__))(MACRO, SEP, CONTEXT, __VA_ARGS__)
73 |
74 | /**
75 | * In consecutive order, appends each variadic argument (up to twenty) onto
76 | * BASE. The resulting concatenations are then separated by SEP.
77 | *
78 | * This is primarily useful to manipulate a list of macro invocations into instead
79 | * invoking a different, possibly related macro.
80 | */
81 | #define metamacro_foreach_concat(BASE, SEP, ...) \
82 | metamacro_foreach_cxt(metamacro_foreach_concat_iter, SEP, BASE, __VA_ARGS__)
83 |
84 | /**
85 | * Iterates COUNT times, each time invoking MACRO with the current index
86 | * (starting at zero) and CONTEXT. The results of adjoining invocations of MACRO
87 | * are then separated by SEP.
88 | *
89 | * COUNT must be an integer between zero and twenty, inclusive.
90 | */
91 | #define metamacro_for_cxt(COUNT, MACRO, SEP, CONTEXT) \
92 | metamacro_concat(metamacro_for_cxt, COUNT)(MACRO, SEP, CONTEXT)
93 |
94 | /**
95 | * Returns the first argument given. At least one argument must be provided.
96 | *
97 | * This is useful when implementing a variadic macro, where you may have only
98 | * one variadic argument, but no way to retrieve it (for example, because \c ...
99 | * always needs to match at least one argument).
100 | *
101 | * @code
102 |
103 | #define varmacro(...) \
104 | metamacro_head(__VA_ARGS__)
105 |
106 | * @endcode
107 | */
108 | #define metamacro_head(...) \
109 | metamacro_head_(__VA_ARGS__, 0)
110 |
111 | /**
112 | * Returns every argument except the first. At least two arguments must be
113 | * provided.
114 | */
115 | #define metamacro_tail(...) \
116 | metamacro_tail_(__VA_ARGS__)
117 |
118 | /**
119 | * Returns the first N (up to twenty) variadic arguments as a new argument list.
120 | * At least N variadic arguments must be provided.
121 | */
122 | #define metamacro_take(N, ...) \
123 | metamacro_concat(metamacro_take, N)(__VA_ARGS__)
124 |
125 | /**
126 | * Removes the first N (up to twenty) variadic arguments from the given argument
127 | * list. At least N variadic arguments must be provided.
128 | */
129 | #define metamacro_drop(N, ...) \
130 | metamacro_concat(metamacro_drop, N)(__VA_ARGS__)
131 |
132 | /**
133 | * Decrements VAL, which must be a number between zero and twenty, inclusive.
134 | *
135 | * This is primarily useful when dealing with indexes and counts in
136 | * metaprogramming.
137 | */
138 | #define metamacro_dec(VAL) \
139 | metamacro_at(VAL, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19)
140 |
141 | /**
142 | * Increments VAL, which must be a number between zero and twenty, inclusive.
143 | *
144 | * This is primarily useful when dealing with indexes and counts in
145 | * metaprogramming.
146 | */
147 | #define metamacro_inc(VAL) \
148 | metamacro_at(VAL, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21)
149 |
150 | /**
151 | * If A is equal to B, the next argument list is expanded; otherwise, the
152 | * argument list after that is expanded. A and B must be numbers between zero
153 | * and twenty, inclusive. Additionally, B must be greater than or equal to A.
154 | *
155 | * @code
156 |
157 | // expands to true
158 | metamacro_if_eq(0, 0)(true)(false)
159 |
160 | // expands to false
161 | metamacro_if_eq(0, 1)(true)(false)
162 |
163 | * @endcode
164 | *
165 | * This is primarily useful when dealing with indexes and counts in
166 | * metaprogramming.
167 | */
168 | #define metamacro_if_eq(A, B) \
169 | metamacro_concat(metamacro_if_eq, A)(B)
170 |
171 | /**
172 | * Identical to #metamacro_if_eq. This can be used when the former would fail
173 | * due to recursive macro expansion.
174 | */
175 | #define metamacro_if_eq_recursive(A, B) \
176 | metamacro_concat(metamacro_if_eq_recursive, A)(B)
177 |
178 | /**
179 | * Returns 1 if N is an even number, or 0 otherwise. N must be between zero and
180 | * twenty, inclusive.
181 | *
182 | * For the purposes of this test, zero is considered even.
183 | */
184 | #define metamacro_is_even(N) \
185 | metamacro_at(N, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1)
186 |
187 | /**
188 | * Returns the logical NOT of B, which must be the number zero or one.
189 | */
190 | #define metamacro_not(B) \
191 | metamacro_at(B, 1, 0)
192 |
193 | // IMPLEMENTATION DETAILS FOLLOW!
194 | // Do not write code that depends on anything below this line.
195 | #define metamacro_stringify_(VALUE) # VALUE
196 | #define metamacro_concat_(A, B) A ## B
197 | #define metamacro_foreach_iter(INDEX, MACRO, ARG) MACRO(INDEX, ARG)
198 | #define metamacro_head_(FIRST, ...) FIRST
199 | #define metamacro_tail_(FIRST, ...) __VA_ARGS__
200 | #define metamacro_consume_(...)
201 | #define metamacro_expand_(...) __VA_ARGS__
202 |
203 | // implemented from scratch so that metamacro_concat() doesn't end up nesting
204 | #define metamacro_foreach_concat_iter(INDEX, BASE, ARG) metamacro_foreach_concat_iter_(BASE, ARG)
205 | #define metamacro_foreach_concat_iter_(BASE, ARG) BASE ## ARG
206 |
207 | // metamacro_at expansions
208 | #define metamacro_at0(...) metamacro_head(__VA_ARGS__)
209 | #define metamacro_at1(_0, ...) metamacro_head(__VA_ARGS__)
210 | #define metamacro_at2(_0, _1, ...) metamacro_head(__VA_ARGS__)
211 | #define metamacro_at3(_0, _1, _2, ...) metamacro_head(__VA_ARGS__)
212 | #define metamacro_at4(_0, _1, _2, _3, ...) metamacro_head(__VA_ARGS__)
213 | #define metamacro_at5(_0, _1, _2, _3, _4, ...) metamacro_head(__VA_ARGS__)
214 | #define metamacro_at6(_0, _1, _2, _3, _4, _5, ...) metamacro_head(__VA_ARGS__)
215 | #define metamacro_at7(_0, _1, _2, _3, _4, _5, _6, ...) metamacro_head(__VA_ARGS__)
216 | #define metamacro_at8(_0, _1, _2, _3, _4, _5, _6, _7, ...) metamacro_head(__VA_ARGS__)
217 | #define metamacro_at9(_0, _1, _2, _3, _4, _5, _6, _7, _8, ...) metamacro_head(__VA_ARGS__)
218 | #define metamacro_at10(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, ...) metamacro_head(__VA_ARGS__)
219 | #define metamacro_at11(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, ...) metamacro_head(__VA_ARGS__)
220 | #define metamacro_at12(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, ...) metamacro_head(__VA_ARGS__)
221 | #define metamacro_at13(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, ...) metamacro_head(__VA_ARGS__)
222 | #define metamacro_at14(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, ...) metamacro_head(__VA_ARGS__)
223 | #define metamacro_at15(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, ...) metamacro_head(__VA_ARGS__)
224 | #define metamacro_at16(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, ...) metamacro_head(__VA_ARGS__)
225 | #define metamacro_at17(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, ...) metamacro_head(__VA_ARGS__)
226 | #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__)
227 | #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__)
228 | #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__)
229 |
230 | // metamacro_foreach_cxt expansions
231 | #define metamacro_foreach_cxt0(MACRO, SEP, CONTEXT)
232 | #define metamacro_foreach_cxt1(MACRO, SEP, CONTEXT, _0) MACRO(0, CONTEXT, _0)
233 |
234 | #define metamacro_foreach_cxt2(MACRO, SEP, CONTEXT, _0, _1) \
235 | metamacro_foreach_cxt1(MACRO, SEP, CONTEXT, _0) \
236 | SEP \
237 | MACRO(1, CONTEXT, _1)
238 |
239 | #define metamacro_foreach_cxt3(MACRO, SEP, CONTEXT, _0, _1, _2) \
240 | metamacro_foreach_cxt2(MACRO, SEP, CONTEXT, _0, _1) \
241 | SEP \
242 | MACRO(2, CONTEXT, _2)
243 |
244 | #define metamacro_foreach_cxt4(MACRO, SEP, CONTEXT, _0, _1, _2, _3) \
245 | metamacro_foreach_cxt3(MACRO, SEP, CONTEXT, _0, _1, _2) \
246 | SEP \
247 | MACRO(3, CONTEXT, _3)
248 |
249 | #define metamacro_foreach_cxt5(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4) \
250 | metamacro_foreach_cxt4(MACRO, SEP, CONTEXT, _0, _1, _2, _3) \
251 | SEP \
252 | MACRO(4, CONTEXT, _4)
253 |
254 | #define metamacro_foreach_cxt6(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5) \
255 | metamacro_foreach_cxt5(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4) \
256 | SEP \
257 | MACRO(5, CONTEXT, _5)
258 |
259 | #define metamacro_foreach_cxt7(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6) \
260 | metamacro_foreach_cxt6(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5) \
261 | SEP \
262 | MACRO(6, CONTEXT, _6)
263 |
264 | #define metamacro_foreach_cxt8(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7) \
265 | metamacro_foreach_cxt7(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6) \
266 | SEP \
267 | MACRO(7, CONTEXT, _7)
268 |
269 | #define metamacro_foreach_cxt9(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8) \
270 | metamacro_foreach_cxt8(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7) \
271 | SEP \
272 | MACRO(8, CONTEXT, _8)
273 |
274 | #define metamacro_foreach_cxt10(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9) \
275 | metamacro_foreach_cxt9(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8) \
276 | SEP \
277 | MACRO(9, CONTEXT, _9)
278 |
279 | #define metamacro_foreach_cxt11(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) \
280 | metamacro_foreach_cxt10(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9) \
281 | SEP \
282 | MACRO(10, CONTEXT, _10)
283 |
284 | #define metamacro_foreach_cxt12(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11) \
285 | metamacro_foreach_cxt11(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) \
286 | SEP \
287 | MACRO(11, CONTEXT, _11)
288 |
289 | #define metamacro_foreach_cxt13(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12) \
290 | metamacro_foreach_cxt12(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11) \
291 | SEP \
292 | MACRO(12, CONTEXT, _12)
293 |
294 | #define metamacro_foreach_cxt14(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13) \
295 | metamacro_foreach_cxt13(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12) \
296 | SEP \
297 | MACRO(13, CONTEXT, _13)
298 |
299 | #define metamacro_foreach_cxt15(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14) \
300 | metamacro_foreach_cxt14(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13) \
301 | SEP \
302 | MACRO(14, CONTEXT, _14)
303 |
304 | #define metamacro_foreach_cxt16(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15) \
305 | metamacro_foreach_cxt15(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14) \
306 | SEP \
307 | MACRO(15, CONTEXT, _15)
308 |
309 | #define metamacro_foreach_cxt17(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16) \
310 | metamacro_foreach_cxt16(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15) \
311 | SEP \
312 | MACRO(16, CONTEXT, _16)
313 |
314 | #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) \
315 | metamacro_foreach_cxt17(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16) \
316 | SEP \
317 | MACRO(17, CONTEXT, _17)
318 |
319 | #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) \
320 | metamacro_foreach_cxt18(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17) \
321 | SEP \
322 | MACRO(18, CONTEXT, _18)
323 |
324 | #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) \
325 | 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) \
326 | SEP \
327 | MACRO(19, CONTEXT, _19)
328 |
329 | // metamacro_foreach_cxt_recursive expansions
330 | #define metamacro_foreach_cxt_recursive0(MACRO, SEP, CONTEXT)
331 | #define metamacro_foreach_cxt_recursive1(MACRO, SEP, CONTEXT, _0) MACRO(0, CONTEXT, _0)
332 |
333 | #define metamacro_foreach_cxt_recursive2(MACRO, SEP, CONTEXT, _0, _1) \
334 | metamacro_foreach_cxt_recursive1(MACRO, SEP, CONTEXT, _0) \
335 | SEP \
336 | MACRO(1, CONTEXT, _1)
337 |
338 | #define metamacro_foreach_cxt_recursive3(MACRO, SEP, CONTEXT, _0, _1, _2) \
339 | metamacro_foreach_cxt_recursive2(MACRO, SEP, CONTEXT, _0, _1) \
340 | SEP \
341 | MACRO(2, CONTEXT, _2)
342 |
343 | #define metamacro_foreach_cxt_recursive4(MACRO, SEP, CONTEXT, _0, _1, _2, _3) \
344 | metamacro_foreach_cxt_recursive3(MACRO, SEP, CONTEXT, _0, _1, _2) \
345 | SEP \
346 | MACRO(3, CONTEXT, _3)
347 |
348 | #define metamacro_foreach_cxt_recursive5(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4) \
349 | metamacro_foreach_cxt_recursive4(MACRO, SEP, CONTEXT, _0, _1, _2, _3) \
350 | SEP \
351 | MACRO(4, CONTEXT, _4)
352 |
353 | #define metamacro_foreach_cxt_recursive6(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5) \
354 | metamacro_foreach_cxt_recursive5(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4) \
355 | SEP \
356 | MACRO(5, CONTEXT, _5)
357 |
358 | #define metamacro_foreach_cxt_recursive7(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6) \
359 | metamacro_foreach_cxt_recursive6(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5) \
360 | SEP \
361 | MACRO(6, CONTEXT, _6)
362 |
363 | #define metamacro_foreach_cxt_recursive8(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7) \
364 | metamacro_foreach_cxt_recursive7(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6) \
365 | SEP \
366 | MACRO(7, CONTEXT, _7)
367 |
368 | #define metamacro_foreach_cxt_recursive9(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8) \
369 | metamacro_foreach_cxt_recursive8(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7) \
370 | SEP \
371 | MACRO(8, CONTEXT, _8)
372 |
373 | #define metamacro_foreach_cxt_recursive10(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9) \
374 | metamacro_foreach_cxt_recursive9(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8) \
375 | SEP \
376 | MACRO(9, CONTEXT, _9)
377 |
378 | #define metamacro_foreach_cxt_recursive11(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) \
379 | metamacro_foreach_cxt_recursive10(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9) \
380 | SEP \
381 | MACRO(10, CONTEXT, _10)
382 |
383 | #define metamacro_foreach_cxt_recursive12(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11) \
384 | metamacro_foreach_cxt_recursive11(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) \
385 | SEP \
386 | MACRO(11, CONTEXT, _11)
387 |
388 | #define metamacro_foreach_cxt_recursive13(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12) \
389 | metamacro_foreach_cxt_recursive12(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11) \
390 | SEP \
391 | MACRO(12, CONTEXT, _12)
392 |
393 | #define metamacro_foreach_cxt_recursive14(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13) \
394 | metamacro_foreach_cxt_recursive13(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12) \
395 | SEP \
396 | MACRO(13, CONTEXT, _13)
397 |
398 | #define metamacro_foreach_cxt_recursive15(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14) \
399 | metamacro_foreach_cxt_recursive14(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13) \
400 | SEP \
401 | MACRO(14, CONTEXT, _14)
402 |
403 | #define metamacro_foreach_cxt_recursive16(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15) \
404 | metamacro_foreach_cxt_recursive15(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14) \
405 | SEP \
406 | MACRO(15, CONTEXT, _15)
407 |
408 | #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) \
409 | metamacro_foreach_cxt_recursive16(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15) \
410 | SEP \
411 | MACRO(16, CONTEXT, _16)
412 |
413 | #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) \
414 | metamacro_foreach_cxt_recursive17(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16) \
415 | SEP \
416 | MACRO(17, CONTEXT, _17)
417 |
418 | #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) \
419 | 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) \
420 | SEP \
421 | MACRO(18, CONTEXT, _18)
422 |
423 | #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) \
424 | 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) \
425 | SEP \
426 | MACRO(19, CONTEXT, _19)
427 |
428 | // metamacro_for_cxt expansions
429 | #define metamacro_for_cxt0(MACRO, SEP, CONTEXT)
430 | #define metamacro_for_cxt1(MACRO, SEP, CONTEXT) MACRO(0, CONTEXT)
431 |
432 | #define metamacro_for_cxt2(MACRO, SEP, CONTEXT) \
433 | metamacro_for_cxt1(MACRO, SEP, CONTEXT) \
434 | SEP \
435 | MACRO(1, CONTEXT)
436 |
437 | #define metamacro_for_cxt3(MACRO, SEP, CONTEXT) \
438 | metamacro_for_cxt2(MACRO, SEP, CONTEXT) \
439 | SEP \
440 | MACRO(2, CONTEXT)
441 |
442 | #define metamacro_for_cxt4(MACRO, SEP, CONTEXT) \
443 | metamacro_for_cxt3(MACRO, SEP, CONTEXT) \
444 | SEP \
445 | MACRO(3, CONTEXT)
446 |
447 | #define metamacro_for_cxt5(MACRO, SEP, CONTEXT) \
448 | metamacro_for_cxt4(MACRO, SEP, CONTEXT) \
449 | SEP \
450 | MACRO(4, CONTEXT)
451 |
452 | #define metamacro_for_cxt6(MACRO, SEP, CONTEXT) \
453 | metamacro_for_cxt5(MACRO, SEP, CONTEXT) \
454 | SEP \
455 | MACRO(5, CONTEXT)
456 |
457 | #define metamacro_for_cxt7(MACRO, SEP, CONTEXT) \
458 | metamacro_for_cxt6(MACRO, SEP, CONTEXT) \
459 | SEP \
460 | MACRO(6, CONTEXT)
461 |
462 | #define metamacro_for_cxt8(MACRO, SEP, CONTEXT) \
463 | metamacro_for_cxt7(MACRO, SEP, CONTEXT) \
464 | SEP \
465 | MACRO(7, CONTEXT)
466 |
467 | #define metamacro_for_cxt9(MACRO, SEP, CONTEXT) \
468 | metamacro_for_cxt8(MACRO, SEP, CONTEXT) \
469 | SEP \
470 | MACRO(8, CONTEXT)
471 |
472 | #define metamacro_for_cxt10(MACRO, SEP, CONTEXT) \
473 | metamacro_for_cxt9(MACRO, SEP, CONTEXT) \
474 | SEP \
475 | MACRO(9, CONTEXT)
476 |
477 | #define metamacro_for_cxt11(MACRO, SEP, CONTEXT) \
478 | metamacro_for_cxt10(MACRO, SEP, CONTEXT) \
479 | SEP \
480 | MACRO(10, CONTEXT)
481 |
482 | #define metamacro_for_cxt12(MACRO, SEP, CONTEXT) \
483 | metamacro_for_cxt11(MACRO, SEP, CONTEXT) \
484 | SEP \
485 | MACRO(11, CONTEXT)
486 |
487 | #define metamacro_for_cxt13(MACRO, SEP, CONTEXT) \
488 | metamacro_for_cxt12(MACRO, SEP, CONTEXT) \
489 | SEP \
490 | MACRO(12, CONTEXT)
491 |
492 | #define metamacro_for_cxt14(MACRO, SEP, CONTEXT) \
493 | metamacro_for_cxt13(MACRO, SEP, CONTEXT) \
494 | SEP \
495 | MACRO(13, CONTEXT)
496 |
497 | #define metamacro_for_cxt15(MACRO, SEP, CONTEXT) \
498 | metamacro_for_cxt14(MACRO, SEP, CONTEXT) \
499 | SEP \
500 | MACRO(14, CONTEXT)
501 |
502 | #define metamacro_for_cxt16(MACRO, SEP, CONTEXT) \
503 | metamacro_for_cxt15(MACRO, SEP, CONTEXT) \
504 | SEP \
505 | MACRO(15, CONTEXT)
506 |
507 | #define metamacro_for_cxt17(MACRO, SEP, CONTEXT) \
508 | metamacro_for_cxt16(MACRO, SEP, CONTEXT) \
509 | SEP \
510 | MACRO(16, CONTEXT)
511 |
512 | #define metamacro_for_cxt18(MACRO, SEP, CONTEXT) \
513 | metamacro_for_cxt17(MACRO, SEP, CONTEXT) \
514 | SEP \
515 | MACRO(17, CONTEXT)
516 |
517 | #define metamacro_for_cxt19(MACRO, SEP, CONTEXT) \
518 | metamacro_for_cxt18(MACRO, SEP, CONTEXT) \
519 | SEP \
520 | MACRO(18, CONTEXT)
521 |
522 | #define metamacro_for_cxt20(MACRO, SEP, CONTEXT) \
523 | metamacro_for_cxt19(MACRO, SEP, CONTEXT) \
524 | SEP \
525 | MACRO(19, CONTEXT)
526 |
527 | // metamacro_if_eq expansions
528 | #define metamacro_if_eq0(VALUE) \
529 | metamacro_concat(metamacro_if_eq0_, VALUE)
530 |
531 | #define metamacro_if_eq0_0(...) __VA_ARGS__ metamacro_consume_
532 | #define metamacro_if_eq0_1(...) metamacro_expand_
533 | #define metamacro_if_eq0_2(...) metamacro_expand_
534 | #define metamacro_if_eq0_3(...) metamacro_expand_
535 | #define metamacro_if_eq0_4(...) metamacro_expand_
536 | #define metamacro_if_eq0_5(...) metamacro_expand_
537 | #define metamacro_if_eq0_6(...) metamacro_expand_
538 | #define metamacro_if_eq0_7(...) metamacro_expand_
539 | #define metamacro_if_eq0_8(...) metamacro_expand_
540 | #define metamacro_if_eq0_9(...) metamacro_expand_
541 | #define metamacro_if_eq0_10(...) metamacro_expand_
542 | #define metamacro_if_eq0_11(...) metamacro_expand_
543 | #define metamacro_if_eq0_12(...) metamacro_expand_
544 | #define metamacro_if_eq0_13(...) metamacro_expand_
545 | #define metamacro_if_eq0_14(...) metamacro_expand_
546 | #define metamacro_if_eq0_15(...) metamacro_expand_
547 | #define metamacro_if_eq0_16(...) metamacro_expand_
548 | #define metamacro_if_eq0_17(...) metamacro_expand_
549 | #define metamacro_if_eq0_18(...) metamacro_expand_
550 | #define metamacro_if_eq0_19(...) metamacro_expand_
551 | #define metamacro_if_eq0_20(...) metamacro_expand_
552 |
553 | #define metamacro_if_eq1(VALUE) metamacro_if_eq0(metamacro_dec(VALUE))
554 | #define metamacro_if_eq2(VALUE) metamacro_if_eq1(metamacro_dec(VALUE))
555 | #define metamacro_if_eq3(VALUE) metamacro_if_eq2(metamacro_dec(VALUE))
556 | #define metamacro_if_eq4(VALUE) metamacro_if_eq3(metamacro_dec(VALUE))
557 | #define metamacro_if_eq5(VALUE) metamacro_if_eq4(metamacro_dec(VALUE))
558 | #define metamacro_if_eq6(VALUE) metamacro_if_eq5(metamacro_dec(VALUE))
559 | #define metamacro_if_eq7(VALUE) metamacro_if_eq6(metamacro_dec(VALUE))
560 | #define metamacro_if_eq8(VALUE) metamacro_if_eq7(metamacro_dec(VALUE))
561 | #define metamacro_if_eq9(VALUE) metamacro_if_eq8(metamacro_dec(VALUE))
562 | #define metamacro_if_eq10(VALUE) metamacro_if_eq9(metamacro_dec(VALUE))
563 | #define metamacro_if_eq11(VALUE) metamacro_if_eq10(metamacro_dec(VALUE))
564 | #define metamacro_if_eq12(VALUE) metamacro_if_eq11(metamacro_dec(VALUE))
565 | #define metamacro_if_eq13(VALUE) metamacro_if_eq12(metamacro_dec(VALUE))
566 | #define metamacro_if_eq14(VALUE) metamacro_if_eq13(metamacro_dec(VALUE))
567 | #define metamacro_if_eq15(VALUE) metamacro_if_eq14(metamacro_dec(VALUE))
568 | #define metamacro_if_eq16(VALUE) metamacro_if_eq15(metamacro_dec(VALUE))
569 | #define metamacro_if_eq17(VALUE) metamacro_if_eq16(metamacro_dec(VALUE))
570 | #define metamacro_if_eq18(VALUE) metamacro_if_eq17(metamacro_dec(VALUE))
571 | #define metamacro_if_eq19(VALUE) metamacro_if_eq18(metamacro_dec(VALUE))
572 | #define metamacro_if_eq20(VALUE) metamacro_if_eq19(metamacro_dec(VALUE))
573 |
574 | // metamacro_if_eq_recursive expansions
575 | #define metamacro_if_eq_recursive0(VALUE) \
576 | metamacro_concat(metamacro_if_eq_recursive0_, VALUE)
577 |
578 | #define metamacro_if_eq_recursive0_0(...) __VA_ARGS__ metamacro_consume_
579 | #define metamacro_if_eq_recursive0_1(...) metamacro_expand_
580 | #define metamacro_if_eq_recursive0_2(...) metamacro_expand_
581 | #define metamacro_if_eq_recursive0_3(...) metamacro_expand_
582 | #define metamacro_if_eq_recursive0_4(...) metamacro_expand_
583 | #define metamacro_if_eq_recursive0_5(...) metamacro_expand_
584 | #define metamacro_if_eq_recursive0_6(...) metamacro_expand_
585 | #define metamacro_if_eq_recursive0_7(...) metamacro_expand_
586 | #define metamacro_if_eq_recursive0_8(...) metamacro_expand_
587 | #define metamacro_if_eq_recursive0_9(...) metamacro_expand_
588 | #define metamacro_if_eq_recursive0_10(...) metamacro_expand_
589 | #define metamacro_if_eq_recursive0_11(...) metamacro_expand_
590 | #define metamacro_if_eq_recursive0_12(...) metamacro_expand_
591 | #define metamacro_if_eq_recursive0_13(...) metamacro_expand_
592 | #define metamacro_if_eq_recursive0_14(...) metamacro_expand_
593 | #define metamacro_if_eq_recursive0_15(...) metamacro_expand_
594 | #define metamacro_if_eq_recursive0_16(...) metamacro_expand_
595 | #define metamacro_if_eq_recursive0_17(...) metamacro_expand_
596 | #define metamacro_if_eq_recursive0_18(...) metamacro_expand_
597 | #define metamacro_if_eq_recursive0_19(...) metamacro_expand_
598 | #define metamacro_if_eq_recursive0_20(...) metamacro_expand_
599 |
600 | #define metamacro_if_eq_recursive1(VALUE) metamacro_if_eq_recursive0(metamacro_dec(VALUE))
601 | #define metamacro_if_eq_recursive2(VALUE) metamacro_if_eq_recursive1(metamacro_dec(VALUE))
602 | #define metamacro_if_eq_recursive3(VALUE) metamacro_if_eq_recursive2(metamacro_dec(VALUE))
603 | #define metamacro_if_eq_recursive4(VALUE) metamacro_if_eq_recursive3(metamacro_dec(VALUE))
604 | #define metamacro_if_eq_recursive5(VALUE) metamacro_if_eq_recursive4(metamacro_dec(VALUE))
605 | #define metamacro_if_eq_recursive6(VALUE) metamacro_if_eq_recursive5(metamacro_dec(VALUE))
606 | #define metamacro_if_eq_recursive7(VALUE) metamacro_if_eq_recursive6(metamacro_dec(VALUE))
607 | #define metamacro_if_eq_recursive8(VALUE) metamacro_if_eq_recursive7(metamacro_dec(VALUE))
608 | #define metamacro_if_eq_recursive9(VALUE) metamacro_if_eq_recursive8(metamacro_dec(VALUE))
609 | #define metamacro_if_eq_recursive10(VALUE) metamacro_if_eq_recursive9(metamacro_dec(VALUE))
610 | #define metamacro_if_eq_recursive11(VALUE) metamacro_if_eq_recursive10(metamacro_dec(VALUE))
611 | #define metamacro_if_eq_recursive12(VALUE) metamacro_if_eq_recursive11(metamacro_dec(VALUE))
612 | #define metamacro_if_eq_recursive13(VALUE) metamacro_if_eq_recursive12(metamacro_dec(VALUE))
613 | #define metamacro_if_eq_recursive14(VALUE) metamacro_if_eq_recursive13(metamacro_dec(VALUE))
614 | #define metamacro_if_eq_recursive15(VALUE) metamacro_if_eq_recursive14(metamacro_dec(VALUE))
615 | #define metamacro_if_eq_recursive16(VALUE) metamacro_if_eq_recursive15(metamacro_dec(VALUE))
616 | #define metamacro_if_eq_recursive17(VALUE) metamacro_if_eq_recursive16(metamacro_dec(VALUE))
617 | #define metamacro_if_eq_recursive18(VALUE) metamacro_if_eq_recursive17(metamacro_dec(VALUE))
618 | #define metamacro_if_eq_recursive19(VALUE) metamacro_if_eq_recursive18(metamacro_dec(VALUE))
619 | #define metamacro_if_eq_recursive20(VALUE) metamacro_if_eq_recursive19(metamacro_dec(VALUE))
620 |
621 | // metamacro_take expansions
622 | #define metamacro_take0(...)
623 | #define metamacro_take1(...) metamacro_head(__VA_ARGS__)
624 | #define metamacro_take2(...) metamacro_head(__VA_ARGS__), metamacro_take1(metamacro_tail(__VA_ARGS__))
625 | #define metamacro_take3(...) metamacro_head(__VA_ARGS__), metamacro_take2(metamacro_tail(__VA_ARGS__))
626 | #define metamacro_take4(...) metamacro_head(__VA_ARGS__), metamacro_take3(metamacro_tail(__VA_ARGS__))
627 | #define metamacro_take5(...) metamacro_head(__VA_ARGS__), metamacro_take4(metamacro_tail(__VA_ARGS__))
628 | #define metamacro_take6(...) metamacro_head(__VA_ARGS__), metamacro_take5(metamacro_tail(__VA_ARGS__))
629 | #define metamacro_take7(...) metamacro_head(__VA_ARGS__), metamacro_take6(metamacro_tail(__VA_ARGS__))
630 | #define metamacro_take8(...) metamacro_head(__VA_ARGS__), metamacro_take7(metamacro_tail(__VA_ARGS__))
631 | #define metamacro_take9(...) metamacro_head(__VA_ARGS__), metamacro_take8(metamacro_tail(__VA_ARGS__))
632 | #define metamacro_take10(...) metamacro_head(__VA_ARGS__), metamacro_take9(metamacro_tail(__VA_ARGS__))
633 | #define metamacro_take11(...) metamacro_head(__VA_ARGS__), metamacro_take10(metamacro_tail(__VA_ARGS__))
634 | #define metamacro_take12(...) metamacro_head(__VA_ARGS__), metamacro_take11(metamacro_tail(__VA_ARGS__))
635 | #define metamacro_take13(...) metamacro_head(__VA_ARGS__), metamacro_take12(metamacro_tail(__VA_ARGS__))
636 | #define metamacro_take14(...) metamacro_head(__VA_ARGS__), metamacro_take13(metamacro_tail(__VA_ARGS__))
637 | #define metamacro_take15(...) metamacro_head(__VA_ARGS__), metamacro_take14(metamacro_tail(__VA_ARGS__))
638 | #define metamacro_take16(...) metamacro_head(__VA_ARGS__), metamacro_take15(metamacro_tail(__VA_ARGS__))
639 | #define metamacro_take17(...) metamacro_head(__VA_ARGS__), metamacro_take16(metamacro_tail(__VA_ARGS__))
640 | #define metamacro_take18(...) metamacro_head(__VA_ARGS__), metamacro_take17(metamacro_tail(__VA_ARGS__))
641 | #define metamacro_take19(...) metamacro_head(__VA_ARGS__), metamacro_take18(metamacro_tail(__VA_ARGS__))
642 | #define metamacro_take20(...) metamacro_head(__VA_ARGS__), metamacro_take19(metamacro_tail(__VA_ARGS__))
643 |
644 | // metamacro_drop expansions
645 | #define metamacro_drop0(...) __VA_ARGS__
646 | #define metamacro_drop1(...) metamacro_tail(__VA_ARGS__)
647 | #define metamacro_drop2(...) metamacro_drop1(metamacro_tail(__VA_ARGS__))
648 | #define metamacro_drop3(...) metamacro_drop2(metamacro_tail(__VA_ARGS__))
649 | #define metamacro_drop4(...) metamacro_drop3(metamacro_tail(__VA_ARGS__))
650 | #define metamacro_drop5(...) metamacro_drop4(metamacro_tail(__VA_ARGS__))
651 | #define metamacro_drop6(...) metamacro_drop5(metamacro_tail(__VA_ARGS__))
652 | #define metamacro_drop7(...) metamacro_drop6(metamacro_tail(__VA_ARGS__))
653 | #define metamacro_drop8(...) metamacro_drop7(metamacro_tail(__VA_ARGS__))
654 | #define metamacro_drop9(...) metamacro_drop8(metamacro_tail(__VA_ARGS__))
655 | #define metamacro_drop10(...) metamacro_drop9(metamacro_tail(__VA_ARGS__))
656 | #define metamacro_drop11(...) metamacro_drop10(metamacro_tail(__VA_ARGS__))
657 | #define metamacro_drop12(...) metamacro_drop11(metamacro_tail(__VA_ARGS__))
658 | #define metamacro_drop13(...) metamacro_drop12(metamacro_tail(__VA_ARGS__))
659 | #define metamacro_drop14(...) metamacro_drop13(metamacro_tail(__VA_ARGS__))
660 | #define metamacro_drop15(...) metamacro_drop14(metamacro_tail(__VA_ARGS__))
661 | #define metamacro_drop16(...) metamacro_drop15(metamacro_tail(__VA_ARGS__))
662 | #define metamacro_drop17(...) metamacro_drop16(metamacro_tail(__VA_ARGS__))
663 | #define metamacro_drop18(...) metamacro_drop17(metamacro_tail(__VA_ARGS__))
664 | #define metamacro_drop19(...) metamacro_drop18(metamacro_tail(__VA_ARGS__))
665 | #define metamacro_drop20(...) metamacro_drop19(metamacro_tail(__VA_ARGS__))
666 |
667 | #endif
668 |
--------------------------------------------------------------------------------