| 438 | // case where shapes may both be standard but have non-identical strides. |
| 439 | #ifndef NDEBUG |
| 440 | static bool is_compatible_shape(const shape& actual, const shape& expected) |
| 441 | { |
| 442 | // Check subshapes |
| 443 | if(expected.type() == shape::tuple_type) |
| 444 | return equal(actual.sub_shapes().begin(), |
| 445 | actual.sub_shapes().end(), |
| 446 | expected.sub_shapes().begin(), |
| 447 | &is_compatible_shape); |
| 448 | // Only the expected can be dynamic |
| 449 | if(expected.dynamic()) |
| 450 | return true; |
| 451 | if(actual == expected) |
| 452 | return true; |
| 453 | if(actual.type() != expected.type()) |
| 454 | return false; |
| 455 | // If both shapes are standard and lens match, they are considered compatible |
| 456 | // even if strides are different. |
| 457 | if(actual.standard() and expected.standard()) |
| 458 | return actual.lens() == expected.lens(); |
| 459 | return false; |
| 460 | } |
| 461 | #endif |
| 462 | |
| 463 | template <class F> |