iOS ビットフラグの使い方

# 数値の書き方

| 2進数 | 10進数 | 16進数 | シフト|
|:--------:|:----:|:----:|:----:|
| 0b000001 | 1 | 0x00001 | 1 << 0 |
| 0b000010 | 2 | 0x00002 | 1 << 1 |
| 0b000100 | 4 | 0x00004 | 1 << 2 |
| 0b001000 | 8 | 0x00008 | 1 << 3 |
| 0b010000 | 16 | 0x00010 | 1 << 4 |
| 0b100000 | 32 | 0x00020 | 1 << 5 |

# Swift

```swift
import XCTest

struct Category : OptionSetType {
    let rawValue: Int32
    static let A = Category(rawValue: 1 << 0)
    static let B = Category(rawValue: 1 << 1)
    static let C = Category(rawValue: 1 << 2)
    static let D = Category(rawValue: 1 << 3)
    static let All : Category = [.A, .B, .C, .D]
}

class BitSampleTests: XCTestCase {
    
    func testExample() {
        //設定
        let type:Category = [.A, .C]
        
        //含まれているかどうかのチェック
        XCTAssertTrue(type.contains(.A))
        XCTAssertFalse(type.contains(.B))
        XCTAssertTrue(type.contains(.C))
        XCTAssertFalse(type.contains(.D))
        XCTAssertTrue(type.contains([.A, .C]))
        XCTAssertFalse(type.contains([.A, .B, .C]))
        
        //Bを追加する (OR)
        let type2 = type.union(.B)
        XCTAssertTrue(type2.contains(.A))
        XCTAssertTrue(type2.contains(.B))
        XCTAssertTrue(type2.contains(.C))
        XCTAssertFalse(type2.contains(.D))
        
        //Aの積 (AND)
        let type3 = type2.intersect(.A)
        XCTAssertTrue(type3.contains(.A))
        XCTAssertFalse(type3.contains(.B))
        XCTAssertFalse(type3.contains(.C))
        XCTAssertFalse(type3.contains(.D))
        
        //Aを排他的論理和(XOR)
        let type4 = type2.exclusiveOr(.A)
        XCTAssertFalse(type4.contains(.A))
        XCTAssertTrue(type4.contains(.B))
        XCTAssertTrue(type4.contains(.C))
        XCTAssertFalse(type4.contains(.D))

        //Aを削除
        let type5 = type2.subtract(.A)
        XCTAssertFalse(type5.contains(.A))
        XCTAssertTrue(type5.contains(.B))
        XCTAssertTrue(type5.contains(.C))
        XCTAssertFalse(type5.contains(.D))
    }
}
```

# ObjectiveC

```objc
#import <XCTest/XCTest.h>

typedef NS_OPTIONS(NSUInteger, Category) {
    CategoryA  = 1 << 0,
    CategoryB  = 1 << 1,
    CategoryC = 1 << 2,
    CategoryD = 1 << 3,
};

@interface ObjeCTests : XCTestCase

@end

@implementation ObjeCTests

- (void)testExample {
    //設定
    Category type = CategoryA | CategoryC;
    
    //含まれているかどうかのチェック
    XCTAssertTrue((type & CategoryA) != 0);
    XCTAssertFalse((type & CategoryB) != 0);
    XCTAssertTrue((type & CategoryC) != 0);
    XCTAssertFalse((type & CategoryD) != 0);
    
    //Bを追加する (OR)
    Category type2 = type | CategoryB;
    XCTAssertTrue((type2 & CategoryA) != 0);
    XCTAssertTrue((type2 & CategoryB) != 0);
    XCTAssertTrue((type2 & CategoryC) != 0);
    XCTAssertFalse((type2 & CategoryD) != 0);
    
    //Aの積 (AND)
    Category type3 = type2 & CategoryA;
    XCTAssertTrue((type3 & CategoryA) != 0);
    XCTAssertFalse((type3 & CategoryB) != 0);
    XCTAssertFalse((type3 & CategoryC) != 0);
    XCTAssertFalse((type3 & CategoryD) != 0);
    
    //Aの排他的論理和(XOR)
    Category type4 = type2 ^ CategoryA;
    XCTAssertFalse((type4 & CategoryA) != 0);
    XCTAssertTrue((type4 & CategoryB) != 0);
    XCTAssertTrue((type4 & CategoryC) != 0);
    XCTAssertFalse((type4 & CategoryD) != 0);

    //Aを削除する (&~)
    Category type5 = type2 & ~CategoryA;
    XCTAssertFalse((type5 & CategoryA) != 0);
    XCTAssertTrue((type5 & CategoryB) != 0);
    XCTAssertTrue((type5 & CategoryC) != 0);
    XCTAssertFalse((type5 & CategoryD) != 0);
}

@end
```