CacheKey: Add a CacheKey class which delegates logic to varying implementations

i.e. a CacheKey class, with implementations such as:
* StrictCacheKey - a normal element when buildstream runs in Strict mode
* NonStrictCacheKey - a normal element when buildstream runs in
  non-strict mode
* StrictWorkspacedCacheKey - a workspaced element when Strict mode
* NonStrictWorkspacedCacheKey - a workspaced element in non-strict mode

(note: only CacheKey and StrictCacheKey are implemented for now)

This involves:
* Creating the CacheKey and StrictCacheKey classes
* In Element instantiation, create a __cache_key_obj to delegate various
  logic to.
* For the moment, extending various functions to call a
  __cache_key_obj's methods if they're implemented.
  * This includesExtending the _KeyStrength enum to include a
    STRICT version, so strict cache keys can be accessed through a
    common interface.
8 files changed