API: allow negative steps for label-based indexing

This should fix #8716.

This is still work-in-progress, but some of its refactoring may be useful for #8613, so I'd like someone to look through this.

cc'ing @shoyer, @jreback and @jorisvandenbossche .

TODO:
- add tests for label slicing with negative step (ix, loc)
   - [x] int64index
   - [x] float64index
   - [x] objectindex
- [x] fix datetime/period indices
-  add tests for label slicing with negative step (datetime, string, native pandas scalar) x (ix, loc)
   - [x] datetimeindex
   - [x] periodindex
   - [x] timedeltaindex
- [ ] clean up old partial string code?
- [ ] benchmark
This one is easy: you just need to add something that throws on invalid type into `_maybe_cast_slice_bound`.  The inverse is tricky (e.g. `pd.Index(list('abc')).slice_indexer(1)`), but should be doable once `StringIndex` lands (either by adding another index type or by adding a string-object numpy dtype).