/*
Copyright (c) Microsoft Corporation
All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in
compliance with the License. You may obtain a copy of the License
at http://www.apache.org/licenses/LICENSE-2.0
THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER
EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF
TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT.
See the Apache Version 2.0 License for specific language governing permissions and
limitations under the License.
*/
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Globalization;
using System.Reflection;
using System.Linq;
using Microsoft.Research.DryadLinq.Internal;
namespace Microsoft.Research.DryadLinq
{
interface IForkValue
{
bool HasValue { get; }
object Value { get; }
}
///
/// Represents an element that may not have valid value.
///
/// The element type
[Serializable]
public struct ForkValue : IForkValue, IEquatable>
{
private T m_x;
private bool m_hasX;
///
/// Initializes an instance of ForkValue{T}. Its element has valid value.
///
/// The value of the element
public ForkValue(T x)
{
this.m_x = x;
this.m_hasX = true;
}
///
/// true iff the value of the element is valid.
///
public bool HasValue
{
get { return this.m_hasX; }
}
object IForkValue.Value
{
get { return this.m_x; }
}
///
/// Gets the value of the element. It is valid only if HasValue returns true.
///
public T Value
{
get { return this.m_x; }
set { this.m_x = value; this.m_hasX = true; }
}
///
/// Gets the hash code of this instance of ForkValue.
///
/// An integer hash code
public override int GetHashCode()
{
if (!this.HasValue)
{
return 0;
}
return this.Value.GetHashCode();
}
///
/// Determines whether the current ForkValue is equal to a specified ForkValue
///
/// A specified ForkValue
/// true iff the current ForkValue is equal to the argument
public bool Equals(ForkValue fval)
{
if (!this.HasValue)
{
return !fval.HasValue;
}
return fval.HasValue && this.Value.Equals(fval.Value);
}
}
///
/// Represents a pair of elements that may not have valid values.
///
/// The type of the first element
/// The type of the second element
[Serializable]
public struct ForkTuple : IEquatable>
{
private T1 m_x;
private T2 m_y;
private bool m_hasX;
private bool m_hasY;
///
/// Initializes an instnace of ForkTuple of two elements. Both elements have valid values.
///
/// The first element
/// The second element
public ForkTuple(T1 x, T2 y)
{
this.m_x = x;
this.m_y = y;
this.m_hasX = true;
this.m_hasY = true;
}
///
/// true iff the value of the first element is valid.
///
public bool HasFirst
{
get { return this.m_hasX; }
}
///
/// true ifff the value of the second element is valid.
///
public bool HasSecond
{
get { return this.m_hasY; }
}
///
/// Gets and sets the first element.
///
public T1 First
{
get { return this.m_x; }
set { this.m_x = value; this.m_hasX = true; }
}
///
/// Gets and sets the second element.
///
public T2 Second
{
get { return this.m_y; }
set { this.m_y = value; this.m_hasY = true; }
}
///
/// Gets the hash code of this instance of ForkTuple.
///
/// An integer hash code
public override int GetHashCode()
{
int hashCode = 0;
if (this.HasFirst)
{
hashCode = (-1521134295 * hashCode) + this.First.GetHashCode();
}
if (this.HasSecond)
{
hashCode = (-1521134295 * hashCode) + this.Second.GetHashCode();
}
return hashCode;
}
///
/// Determines whether the current ForkTuple is equal to a specified ForkTuple.
///
/// A specified ForkTuple
/// true iff the current ForkTuple is equal to the argument
public bool Equals(ForkTuple fval)
{
if (this.HasFirst)
{
if (!fval.HasFirst || !this.First.Equals(fval.First))
{
return false;
}
}
else
{
if (fval.HasFirst) return false;
}
if (this.HasSecond)
{
if (!fval.HasSecond || !this.Second.Equals(fval.Second))
{
return false;
}
}
else
{
if (fval.HasSecond) return false;
}
return true;
}
}
///
/// Represents a tuple of three elements that may not have valid values.
///
/// The type of the first element
/// The type of the second element
/// The type of the third element
[Serializable]
public struct ForkTuple : IEquatable>
{
private T1 m_x;
private T2 m_y;
private T3 m_z;
private bool m_hasX;
private bool m_hasY;
private bool m_hasZ;
///
/// Initializes an instance of ForkTuple of three elements. All the elements have valid values.
///
/// The first element
/// The second element
/// The third element
public ForkTuple(T1 x, T2 y, T3 z)
{
this.m_x = x;
this.m_y = y;
this.m_z = z;
this.m_hasX = true;
this.m_hasY = true;
this.m_hasZ = true;
}
///
/// true iff the value of the first element is valid.
///
public bool HasFirst
{
get { return this.m_hasX; }
}
///
/// true iff the value of the second element is valid.
///
public bool HasSecond
{
get { return this.m_hasY; }
}
///
/// true iff the value of the third element is valid.
///
public bool HasThird
{
get { return this.m_hasZ; }
}
///
/// Gets and sets the first element.
///
public T1 First
{
get { return this.m_x; }
set { this.m_x = value; this.m_hasX = true; }
}
///
/// Gets and sets the second element.
///
public T2 Second
{
get { return this.m_y; }
set { this.m_y = value; this.m_hasY = true; }
}
///
/// Gets and sets the third element.
///
public T3 Third
{
get { return this.m_z; }
set { this.m_z = value; this.m_hasZ = true; }
}
///
/// Gets the hash code of this instance of ForkTuple.
///
/// An integer hash code
public override int GetHashCode()
{
int hashCode = 0;
if (this.HasFirst)
{
hashCode = (-1521134295 * hashCode) + this.First.GetHashCode();
}
if (this.HasSecond)
{
hashCode = (-1521134295 * hashCode) + this.Second.GetHashCode();
}
if (this.HasThird)
{
hashCode = (-1521134295 * hashCode) + this.Third.GetHashCode();
}
return hashCode;
}
///
/// Determines whether the current ForkTuple is equal to a specified ForkTuple.
///
/// A specified ForkTuple
/// true iff the current ForkTuple is equal to the argument
public bool Equals(ForkTuple fval)
{
if (this.HasFirst)
{
if (!fval.HasFirst || !this.First.Equals(fval.First))
{
return false;
}
}
else
{
if (fval.HasFirst) return false;
}
if (this.HasSecond)
{
if (!fval.HasSecond || !this.Second.Equals(fval.Second))
{
return false;
}
}
else
{
if (fval.HasSecond) return false;
}
if (this.HasThird)
{
if (!fval.HasThird || !this.Third.Equals(fval.Third))
{
return false;
}
}
else
{
if (fval.HasThird) return false;
}
return true;
}
}
}