ある範囲内で整数のインクリメント・デクリメントを循環させるには？


「3, 4, 5」という範囲の整数があるとします。カレントロケーションを `5`、インクリメントを `+1` としたとき、`3`
を返してほしいです。もし、インクリメントが `+2` なら `4`、`+7` であれば `3` のように、3, 4, 5, 3, 4, 5, 3...
とインクリメントの結果が循環してほしいです。

**やってみたこと** :

+1、-1 のインクリメント/デクリメントの場合は下記のコードで実装できましたが、+2 や -4 など加減数が 1
を超える場合に対応させようとすると、方法がわからなくなります（下記の関数を加減数ぶんfor文で繰り返し実行することはできますが……）。

実装

[code]

    NSUInteger NSRangeIncrementLocationInRange(NSUInteger location, NSRange range) {
    
      NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange: range];
    
      if (![indexSet containsIndex: location]) {
        return NSNotFound;
      }
    
      NSUInteger index = [indexSet indexGreaterThanIndex: location];
    
      return index != NSNotFound ? index : [indexSet firstIndex];
    }
    
    NSUInteger NSRangeDecrementLocationInRange(NSUInteger location, NSRange range) {
    
      NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange: range];
    
      if (![indexSet containsIndex: location]) {
        return NSNotFound;
      }
    
      NSUInteger index = [indexSet indexLessThanIndex: location];
    
      return index != NSNotFound ? index : [indexSet lastIndex];
    }
    
[/code]

実行例

[code]

    // 4 〜 8の範囲内で8をインクリメントする
    NSLog(@"%zd", NSRangeIncrementLocationInRange(8, NSMakeRange(4, 5))); // 8の次は最小値に戻って4が返る
    
[/code]

**求めているもの** :

理想的なのは下記のような関数で、

[code]

    NSUInteger NSRangeIncrementLocationInRange(NSUInteger location, NSInteger increment, NSRange range);
    
[/code]

`increment` に `3` だの `-8` だの正負どちらでも渡せるようにしたいです。

**質問** :

このようなメソッド、または関数は、Objective-C、またはCのフレームワークやライブラリに存在しますか？
もしない場合、実装するためにどのようなコードが考えられますか？




Cっぽく書けば下記コードで算出できます。一度`range`で剰余(`%`)を求めたあと、負値に対処するため再び`(N + range) %
range`を行っています。

[code]

    // 値(value+diff)を範囲[rl, rh)にマッピング
    int f(int value, int diff, int rl, int rh)
    {
      int range = rh - rl;
      return (((value + diff - rl) % range) + range) % range + rl;
    }
    
[/code]

入力値`value`の範囲チェックはしていませんので、必要ならば別途追加してください（要不要は要件によると思います）。

LiveDemo: <http://melpon.org/wandbox/permlink/4gUve20aihTOVhuz>




Cっぽく書けば下記コードで算出できます。一度`range`で剰余(`%`)を求めたあと、負値に対処するため再び`(N + range) %
range`を行っています。

[code]

    // 値(value+diff)を範囲[rl, rh)にマッピング
    int f(int value, int diff, int rl, int rh)
    {
      int range = rh - rl;
      return (((value + diff - rl) % range) + range) % range + rl;
    }
    
[/code]

入力値`value`の範囲チェックはしていませんので、必要ならば別途追加してください（要不要は要件によると思います）。

LiveDemo: <http://melpon.org/wandbox/permlink/4gUve20aihTOVhuz>

